commit 2d8d0cd44b87c724acbca9f835c2142778007da9 Author: jjgarcia Date: Tue Jun 26 17:14:44 2001 +0000 Initial revision diff --git a/Copyright b/Copyright new file mode 100644 index 000000000..dc590ec98 --- /dev/null +++ b/Copyright @@ -0,0 +1,69 @@ + +_______________________________________________________________________________ + + Copyright (c) 2000, Juan Jose Garcia Ripoll + Copyright (c) 1990, 1991, 1993 Giuseppe Attardi + Copyright (c) 1984 Taiichi Yuasa and Masami Hagiya + All Rights Reserved +_______________________________________________________________________________ + +Summary: + + Permission is granted to use, copy, modify this program, + EXCEPT that the copyright notice must be reproduced on copies, and + credit should be given to the authors where it is due. + WE MAKE NO WARRANTY AND ACCEPT NO LIABILITY FOR THIS PROGRAM. + + +In detail: + + 1. Permission to use, copy, modify this software and its documentation + for any purpose is hereby granted without fee, provided that + - the above copyright notice appears in all copies, + - both that copyright notice and this permission notice appears in + supporting documentation, and that + - you cause modified files to carry prominent notices stating that + you changed the files and the date of any change. + + 2. Please notify us if you are going to sell this software or its + documentation for profit. + + 3. WE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + WE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + + +Additionally: + + ECLS is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 'Copying'. + + 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Address: + + Juan Jose Garcia Ripoll + Univ. de Castilla-La Mancha + E.T.S.I. Industriales + Departamento de Matematicas + c/Camilo Jose Cela, 3 + Ciudad Real, E-13071 + Spain + + +Address for reporting bugs, comments, suggestions: + + jjgarcia@ind-cr.uclm.es diff --git a/LGPL b/LGPL new file mode 100644 index 000000000..eb685a5ec --- /dev/null +++ b/LGPL @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..092306d6e --- /dev/null +++ b/Makefile @@ -0,0 +1,166 @@ +# Generated automatically from Makefile.in by configure. +# DIST: This is the distribution Makefile for ECL. configure can +# DIST: make most of the changes to this file you might want, so try +# DIST: that first. + +# make all to compile and build Emacs. +# make install to install it. +# make TAGS to update tags tables. +# +# make clean or make mostlyclean +# Delete all files from the current directory that are normally +# created by building the program. Don't delete the files that +# record the configuration. Also preserve files that could be made +# by building, but normally aren't because the distribution comes +# with them. +# +# Delete `.dvi' files here if they are not part of the distribution. +# +# make distclean +# Delete all files from the current directory that are created by +# configuring or building the program. If you have unpacked the +# source and built the program without creating any other files, +# `make distclean' should leave only the files that were in the +# distribution. +# +# make realclean +# Delete everything from the current directory that can be +# reconstructed with this Makefile. This typically includes +# everything deleted by distclean. + +SHELL = /bin/sh +MAKE = make # BSD doesn't have it as a default. +MACHINE = freebsd + +# ========================= Last release ================================ + +VERSION=0.2 +WWW=http://ecls.sourceforge.net/ + +# ==================== Things `configure' Might Edit ==================== + +CC=gcc +CPP=gcc -E +LN_S=ln -s +CFLAGS=-g -O2 + +# Where to find the source code. +# This is set by the configure script's `--srcdir' option. +srcdir=/home/jjgarcia/ecl/src + +bindir=/home/jjgarcia/bin +infodir=/home/jjgarcia/info +mandir=/home/jjgarcia/man/man1 +libdir=/home/jjgarcia/lib/ecls + +# What to release +TAR_CONTENTS=Makefile.in Copy* README.1st README.orig doc \ + configure site.lsp src/c src/cmp src/crs src/clos src/lsp src/doc \ + src/h src/etc src/gmp src/config* src/install.sh src/Makefile.in \ + src/util contrib/ src/clx src/tk src/gc src/*.in src/gabriel + +# ==================== Utility Programs for the Build ==================== + +# Allow the user to specify the install program. +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +# ============================= Build ============================== + +all: build/Makefile + cd build; $(MAKE) +.PHONY: all + +Makefile: Makefile.in build/config.status + (cd build; ./config.status) + +# ==================== Installation ==================== + +install: build/Makefile + (cd build; make install) +uninstall: + (cd build; make uninstall) + +# ==================== Documentation ==================== + +info: + (cd ${srcdir}/doc; $(MAKE) info) +dvi: + (cd ${srcdir}/doc; $(MAKE) dvi) + +# ==================== Cleaning up and miscellanea ==================== + +# `clean' +# Delete all files from the current directory that are normally +# created by building the program. Don't delete the files that +# record the configuration. Also preserve files that could be made +# by building, but normally aren't because the distribution comes +# with them. +# +clean: + cd build; $(MAKE) clean + +# `distclean' +# Delete all files from the current directory that are created by +# configuring or building the program. If you have unpacked the +# source and built the program without creating any other files, +# `make distclean' should leave only the files that were in the +# distribution. + +distclean: clean + rm -fr build/config.status + rm -f Makefile + +# `realclean' +# Delete everything from the current directory that can be +# reconstructed with this Makefile. +# One exception, however: `make realclean' should not delete +# `configure' even if `configure' can be remade using a rule in the +# Makefile. More generally, `make realclean' should not delete +# anything that needs to exist in order to run `configure' and then +# begin to build the program. +realclean: distclean + +TAGS tags: + (cd ${srcdir}/src; \ + etags c/*.[cd] h/*.h) + +check: + @echo "We don't have any tests for ECL yet." + +TAR_DIR=ecls-$(VERSION) + +doc: build/doc/index.html + -mkdir doc + cp build/doc/*.html doc +build/doc/index.html: + cd build/doc; make + +source-dist: ecls.tgz ecls-tests.tgz + +ecls.tgz: doc + -rm -rf $(TAR_DIR) + mkdir $(TAR_DIR) $(TAR_DIR)/src && \ + for i in $(TAR_CONTENTS); do cp -rf $$i $(TAR_DIR)/$$i; done && \ + tar -cz --exclude '*~' --exclude '#*' --exclude 'CVS' -f ecls.tgz $(TAR_DIR) + -rm -rf $(TAR_DIR) +ecls-tests.tgz: + -rm -rf $(TAR_DIR) + mkdir $(TAR_DIR) && \ + mkdir $(TAR_DIR)/src && \ + cp -rf src/ansi-tests $(TAR_DIR)/src && \ + tar -cz --exclude '*~' --exclude '#*' --exclude 'CVS' -f ecls-tests.tgz $(TAR_DIR); + -rm -rf $(TAR_DIR) + +binary-dist: all + su -c "rm -rf tmp" + mkdir tmp + for i in $(bindir) $(infodir) $(mandir) $(libdir); do \ + (echo $$i; IFS="/"; for k in tmp/$$i; do echo $$k; (test -d $$k || mkdir $$k); chmod 755 $$k; cd $$k; done); \ + done + PREFIX=`pwd`/tmp; cd build; make install PREFIX="$${PREFIX}" + su -c "chown -R root.root tmp && cd tmp; tar czf ../ecls-$(VERSION)-$(MACHINE).tgz * && cd .. && rm -rf tmp" + +dist: + cd dist; make-dist diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..e9306307c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,165 @@ +# DIST: This is the distribution Makefile for ECL. configure can +# DIST: make most of the changes to this file you might want, so try +# DIST: that first. + +# make all to compile and build Emacs. +# make install to install it. +# make TAGS to update tags tables. +# +# make clean or make mostlyclean +# Delete all files from the current directory that are normally +# created by building the program. Don't delete the files that +# record the configuration. Also preserve files that could be made +# by building, but normally aren't because the distribution comes +# with them. +# +# Delete `.dvi' files here if they are not part of the distribution. +# +# make distclean +# Delete all files from the current directory that are created by +# configuring or building the program. If you have unpacked the +# source and built the program without creating any other files, +# `make distclean' should leave only the files that were in the +# distribution. +# +# make realclean +# Delete everything from the current directory that can be +# reconstructed with this Makefile. This typically includes +# everything deleted by distclean. + +SHELL = /bin/sh +MAKE = make # BSD doesn't have it as a default. +MACHINE = @MACHINE@ + +# ========================= Last release ================================ + +VERSION=@ECLS_VERSION@ +WWW=http://ecls.sourceforge.net/ + +# ==================== Things `configure' Might Edit ==================== + +CC=@CC@ +CPP=@CPP@ +LN_S=@LN_S@ +CFLAGS=@CFLAGS@ + +# Where to find the source code. +# This is set by the configure script's `--srcdir' option. +srcdir=@srcdir@ + +bindir=@bindir@ +infodir=@infodir@ +mandir=@mandir@ +libdir=@libdir@ + +# What to release +TAR_CONTENTS=Makefile.in Copy* README.1st README.orig doc \ + configure site.lsp src/c src/cmp src/crs src/clos src/lsp src/doc \ + src/h src/etc src/gmp src/config* src/install.sh src/Makefile.in \ + src/util contrib/ src/clx src/tk src/gc src/*.in src/gabriel + +# ==================== Utility Programs for the Build ==================== + +# Allow the user to specify the install program. +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +# ============================= Build ============================== + +all: build/Makefile + cd build; $(MAKE) +.PHONY: all + +Makefile: Makefile.in build/config.status + (cd build; ./config.status) + +# ==================== Installation ==================== + +install: build/Makefile + (cd build; make install) +uninstall: + (cd build; make uninstall) + +# ==================== Documentation ==================== + +info: + (cd ${srcdir}/doc; $(MAKE) info) +dvi: + (cd ${srcdir}/doc; $(MAKE) dvi) + +# ==================== Cleaning up and miscellanea ==================== + +# `clean' +# Delete all files from the current directory that are normally +# created by building the program. Don't delete the files that +# record the configuration. Also preserve files that could be made +# by building, but normally aren't because the distribution comes +# with them. +# +clean: + cd build; $(MAKE) clean + +# `distclean' +# Delete all files from the current directory that are created by +# configuring or building the program. If you have unpacked the +# source and built the program without creating any other files, +# `make distclean' should leave only the files that were in the +# distribution. + +distclean: clean + rm -fr build/config.status + rm -f Makefile + +# `realclean' +# Delete everything from the current directory that can be +# reconstructed with this Makefile. +# One exception, however: `make realclean' should not delete +# `configure' even if `configure' can be remade using a rule in the +# Makefile. More generally, `make realclean' should not delete +# anything that needs to exist in order to run `configure' and then +# begin to build the program. +realclean: distclean + +TAGS tags: + (cd ${srcdir}/src; \ + etags c/*.[cd] h/*.h) + +check: + @echo "We don't have any tests for ECL yet." + +TAR_DIR=ecls-$(VERSION) + +doc: build/doc/index.html + -mkdir doc + cp build/doc/*.html doc +build/doc/index.html: + cd build/doc; make + +source-dist: ecls.tgz ecls-tests.tgz + +ecls.tgz: doc + -rm -rf $(TAR_DIR) + mkdir $(TAR_DIR) $(TAR_DIR)/src && \ + for i in $(TAR_CONTENTS); do cp -rf $$i $(TAR_DIR)/$$i; done && \ + tar -cz --exclude '*~' --exclude '#*' --exclude 'CVS' -f ecls.tgz $(TAR_DIR) + -rm -rf $(TAR_DIR) +ecls-tests.tgz: + -rm -rf $(TAR_DIR) + mkdir $(TAR_DIR) && \ + mkdir $(TAR_DIR)/src && \ + cp -rf src/ansi-tests $(TAR_DIR)/src && \ + tar -cz --exclude '*~' --exclude '#*' --exclude 'CVS' -f ecls-tests.tgz $(TAR_DIR); + -rm -rf $(TAR_DIR) + +binary-dist: all + su -c "rm -rf tmp" + mkdir tmp + for i in $(bindir) $(infodir) $(mandir) $(libdir); do \ + (echo $$i; IFS="/"; for k in tmp/$$i; do echo $$k; (test -d $$k || mkdir $$k); chmod 755 $$k; cd $$k; done); \ + done + PREFIX=`pwd`/tmp; cd build; make install PREFIX="$${PREFIX}" + su -c "chown -R root.root tmp && cd tmp; tar czf ../ecls-$(VERSION)-$(MACHINE).tgz * && cd .. && rm -rf tmp" + +dist: + cd dist; make-dist diff --git a/README.1st b/README.1st new file mode 100644 index 000000000..8c3629d38 --- /dev/null +++ b/README.1st @@ -0,0 +1 @@ +You can find the preprocessed documentation in ./doc in HTML format. diff --git a/configure b/configure new file mode 100755 index 000000000..c2b656b5f --- /dev/null +++ b/configure @@ -0,0 +1,20 @@ +#!/bin/sh +# +# This is just a driver for configure, the real configure is in src. +# This script identifies the machine, and creates a directory for +# the installation, where it runs ${srcdir}/configure. + +srcdir=`pwd`/src +buildir=build + +if [ ! -d ${buildir} ] ; then + echo Creating directory "\`${buildir}'" + mkdir ${buildir} +fi + +# Now run the real configure script +echo Switching to directory "\`${buildir}'" to continue configuration. +cd ${buildir} +${srcdir}/configure --srcdir=${srcdir} $* + +echo Configuration complete. To build ECL, issue 'make' in this directory. diff --git a/contrib/logical-pathnames.ecl b/contrib/logical-pathnames.ecl new file mode 100644 index 000000000..dbc028eb3 --- /dev/null +++ b/contrib/logical-pathnames.ecl @@ -0,0 +1,1951 @@ +;;; -*- Mode: LISP; Package: LOGICAL-PATHNAME; Syntax: Common-lisp; -*- +;;; Tue Apr 9 19:17:01 1991 by Mark Kantrowitz +;;; logical-pathnames.lisp + +;;; **************************************************************** +;;; Logical Pathnames System *************************************** +;;; **************************************************************** +;;; +;;; Logical Pathnames provide a facility for referring to pathnames +;;; in a portable manner. Logical pathnames are mapped to physical +;;; pathnames by a set of implementation dependent and site-dependent +;;; rules. +;;; +;;; This system is a Common Lisp portable implementation of logical +;;; pathnames. It fulfills most of the X3J13 June 1989 specification +;;; for logical pathnames, as documented in Guy Steele's "Common Lisp: +;;; The Language" (2nd Edition), section 23.1.5 "Logical Pathnames". +;;; +;;; Written by Mark Kantrowitz, July 1990. +;;; +;;; Address: Carnegie Mellon University +;;; School of Computer Science +;;; Pittsburgh, PA 15213 +;;; +;;; This code is in the public domain and is distributed without warranty +;;; of any kind. +;;; +;;; Use and copying of this software and preparation of derivative works +;;; based upon this software are permitted, so long as the following +;;; conditions are met: +;;; o no fees or compensation are charged for use, copies, or +;;; access to this software +;;; o this copyright notice is included intact. +;;; This software is made available AS IS, and no warranty is made about +;;; the software or its performance. +;;; +;;; Please send bug reports, comments and suggestions to mkant@cs.cmu.edu. +;;; +;;; +;;; Logical Pathnames are especially useful when coupled with a portable +;;; system construction tool, such as the Defsystem facility written +;;; by Mark Kantrowitz. +;;; + +;;; ******************************** +;;; Change Log ********************* +;;; ******************************** +;;; +;;; djc = Daniel J. Clancy +;;; +;;; 30-JUL-90 mk Fixed logical pathnames for VAX-LISP (thanks to +;;; Paul Werkowski). In VAX-LISP simple strings are not +;;; sub-types of simple-vectors, so svref doesn't work +;;; on strings. These calls have been fixed to read +;;; #+:cmu svref #-:cmu aref. +;;; 15-NOV-90 mk Changed convert-file-function to better handle optional +;;; args. This should fix the problem of (ed) and (dribble) +;;; returning errors like "argument NIL must be a number" +;;; in parse-namestring. Note that some lisps seem to make +;;; a distinction between (funcall #'foo) and (foo) with +;;; respect to this error. +;;; 29-JAN-91 mk Defined LISP:NTH-VALUE if not already present (it is +;;; a CLtL2 addition) and used it in LOAD-PHYSICAL-HOSTAB +;;; to avoid needing a GARBAGE variable in +;;; (multiple-value-setq (garbage pos) ...) which we can +;;; not declare ignore and yet causes a compiler warning +;;; since we don't use it. +;;; 29-JAN-91 mk lisp::file-name is particular to CMU Common Lisp +;;; and the #+:cmu's were accidentally left off. +;;; 29-JAN-91 mk Added :explorer physical namestring output to +;;; PHYSICAL-NAMESTRING. +;;; 29-JAN-91 mk Warns about name collisions between physical and logical +;;; host names. +;;; 30-JAN-91 mk Added :logical-pathnames-mk to the *features* list. +;;; 25-FEB-91 mk Added definition of LOAD-LOGICAL-PATHNAME-TRANSLATIONS. +;;; 09-APR-91 mk Export pathname-host-type, append-logical-directories. +;;; 09-APR-91 mk Translation rules now support :case :unchanged. +;;; 09-APR-91 djc Fixed so that (logical-pathname "") returns a +;;; logical-pathname structure. +;;; 21-FEB-96 attardi +;;; Added support for ECL + +;;; ******************************** +;;; To Do ************************** +;;; ******************************** +;;; +;;; Support for Macintosh pathnames. Little tricky, since MACL uses a +;;; colon (:) as the delimiter. +;;; +;;; support for tops-20/tenex, multics, its, ms-dos +;;; add host-type to pathnames +;;; merge-pathnames, with-open-file +;;; +;;; Define generic pathname parsing/printing definition interface. +;;; +;;; Redefine with-open-file? +;;; +;;; Port to emacs-lisp for gnu-emacs? +;;; +;;; Logical pathnames needs to case both on the physical host type and on +;;; lisp type (e.g., for canonicalization). Fix this, and define lots of +;;; canonical types. Dependency on lisp type can probably be handled using +;;; #+ and #-. What about conflicts between canonicalization and the +;;; translations (e.g., "L" vs :lisp)? +;;; + +;;; ******************************** +;;; Notes ************************** +;;; ******************************** +;;; +;;; LOGICAL-PATHNAMES has been tested (successfully) in the following lisps: +;;; CMU Common Lisp (M2.9 15-Aug-90, Compiler M1.8 15-Aug-90) +;;; Macintosh Allegro Common Lisp (1.3.2) +;;; ExCL (Franz Allegro CL 3.1.12 [DEC 3100] 3/30/90) +;;; Lucid CL (Version 2.1 6-DEC-87) +;;; Symbolics Common Lisp (8.0) +;;; Lucid Common Lisp (3.0, 4.0) +;;; VAXLisp (2.0, 3.1) +;;; ECL (ECoLisp) Version(0.23) +;;; +;;; LOGICAL-PATHNAMES needs to be tested in the following lisps: +;;; KCL (June 3, 1987 or later) +;;; AKCL (1.86, June 30, 1987 or later) +;;; TI (Release 4.1 or later) +;;; Ibuki Common Lisp (01/01, October 15, 1987) +;;; Golden Common Lisp (3.1 IBM-PC) +;;; HP Common Lisp (same as Lucid?) +;;; Procyon Common Lisp + + +;;; ******************************** +;;; Documentation ****************** +;;; ******************************** +;;; +;;; Logical pathnames allow large programs to be moved between sites +;;; by separating pathname reference from actual file location. The +;;; program will refer to files using logical pathnames. At each site, +;;; a user will specify a set of "translations" which map from the logical +;;; pathnames to the physical pathnames used on the device. +;;; +;;; Logical pathnames provide a uniform convention for filesystem access, +;;; with the following properties: +;;; 1. Pathname Portability: The program specifies a pathname in +;;; a conventional format (logical pathnames), which may be +;;; mapped reasonably literally (via the translations) to +;;; a variety of filesystems. +;;; 2. Pathname Aliasing: The files may exist in different locations +;;; in the various filesystems. For example, the root directory +;;; might change. The translations allow such a change easily. +;;; 3. Cross-host Access: The files need not all exist on the same +;;; physical host. +;;; +;;; This definition of logical pathnames provides support for physical +;;; pathnames for Unix, VMS/VAX, Symbolics, and TI Explorers, and is +;;; easily extended to handle additional platforms. Code which may need +;;; customization for particular Lisps and platforms has been commented +;;; with three ampersands (&&&). In addition, the user probably should +;;; define their own canonical types, translation rules, and +;;; logical-pathname-translations. Examples are provided. +;;; +;;; Logical pathnames employ the following syntax: +;;; [host:] [;] {directory ;}* [name] [. type [. version]] +;;; host ::= word +;;; directory ::= word | wildcard-word | wildcard-inferiors +;;; name ::= word | wildcard-word +;;; type ::= word | wildcard-word +;;; version ::= word | wildcard-word +;;; word ::= {letter | digit | -}* +;;; wildcard-word ::= [word] * {word *}* [word] +;;; wildcard-inferiors ::= ** +;;; +;;; A wildcard-word of * parses as :wild; all others as strings. These +;;; definitions may be extended (e.g., "newest" parsing as :newest) by +;;; defining new canonical types. +;;; +;;; Incompatibilities with the X3J13 specification: +;;; - LOGICAL-PATHNAME is not defined as a subclass of PATHNAME +;;; since we have no guarrantee about the format of PATHNAME +;;; (i.e., is it a defstruct or a class definition, what are +;;; its slots, etc.). Many Lisps will be able to replace the +;;; definition of PHYSICAL-PATHNAME with their definition of +;;; PATHNAME by doing a string-replace of "physical-pathname" +;;; with "pathname" and deleting some definitions from this file. +;;; - CLtL does not specify the manner in which wildcards are +;;; translated. We use reversible wildcard pathname translation, +;;; similar to that used in the Symbolics logical pathnames. +;;; - COMPILE-FILE-PATHNAME has not been defined, since it is +;;; highly implementation dependent. + +;;; ******************************** +;;; Examples *********************** +;;; ******************************** +;;; +;;; The following examples of the use of logical pathnames are taken +;;; from Section 23.1.5.4 of Guy Steele CLtL 2nd Ed. + +#| +(setf (lp:physical-host-type "MY-LISPM") :symbolics) +(setf (lp:logical-pathname-translations "foo") + '(("**;*.*.*" "MY-LISPM:>library>foo>**>"))) + + (lp:translate-logical-pathname "foo:bar;baz;mum.quux.3" :namestring) +"MY-LISPM:>library>foo>bar>baz>mum.quux.3" + +(setf (lp:physical-host-type "U") :unix) +(setf (lp:physical-host-type "V") :vms) +(setf (lp:logical-pathname-translations "prog") + '(("RELEASED;*.*.*" "U:/sys/bin/my-prog/") + ("RELEASED;*;*.*.*" "U:/sys/bin/my-prog/*/") + ("EXPERIMENTAL;*.*.*" "U:/usr/Joe/development/prog/") + ("EXPERIMENTAL;DOCUMENTATION;*.*.*" "V:SYS$DISK:[JOE.DOC]") + ("EXPERIMENTAL;*;*.*.*" "U:/usr/Joe/development/prog/*/") + ("MAIL;**;*.MAIL" "V:SYS$DISK:[JOE.MAIL.PROG...]*.MBX"))) + + (lp:translate-logical-pathname "prog:mail;save;ideas.mail.3" :namestring) +"V:SYS$DISK:[JOE.MAIL.PROG.SAVE]IDEAS.MBX.3" + (lp:translate-logical-pathname "prog:experimental;spreadsheet.c" :namestring) +"U:/usr/Joe/development/prog/spreadsheet.c" + +(setf (lp:logical-pathname-translations "prog") + '(("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/documentation.lisp" + +(setf (lp:logical-pathname-translations "prog") + '(("CODE;DOCUMENTATION.*.*" "/lib/prog/docum.*") + ("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/docum.lisp" + + +(setf (lp:logical-pathname-translations "prog") + `(("**;*.LISP.*" ,(lp:logical-pathname "PROG:**;*.L.*")) + ("**;*.FASL.*" ,(lp:logical-pathname "PROG:**;*.B.*")) + ("CODE;DOCUMENTATION.*.*" "/lib/prog/documentatio.*") + ("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/documentatio.l" + +|# + +;;; **************************************************************** +;;; Logical Pathnames ********************************************** +;;; **************************************************************** +;;; Putting this in a separate package doesn't prevent collisions +;;; with the LISP package, since this package :uses the LISP +;;; package. +(in-package "LOGICAL-PATHNAME" :nicknames '("LP")) + +(export '(logical-pathname + translate-logical-pathname + logical-pathname-translations + pathname-host-type + append-logical-directories + make-logical-pathname + physical-host-type + load-logical-pathname-translations + load-physical-hostab + define-translation-rule + define-canonical)) + +(pushnew :logical-pathnames-mk *features*) + +;;; ******************************** +;;; Global Variables *************** +;;; ******************************** +(defvar *null-vector* (coerce nil 'simple-vector)) + +(defvar *warn-about-host-type-collisions* t + "Warn user when a logical host type definition collides with a physical + host type definition.") + +;;; ******************************** +;;; Primitives ********************* +;;; ******************************** +(defun parse-with-string-delimiter (delim string &key (start 0) end) + "Returns up to three values: the string up to the delimiter DELIM + in STRING (or NIL if the field is empty), the position of the beginning + of the rest of the string after the delimiter, and a value which, if + non-NIL (:delim-not-found), specifies that the delimiter was not found." + (declare (simple-string string)) + ;; Conceivably, if DELIM is a string consisting of a single character, + ;; we could do this more efficiently using POSITION instead of SEARCH. + ;; However, any good implementation of SEARCH should optimize for that + ;; case, so nothing to worry about. + (setq end (or end (length string))) + (let ((delim-pos (search delim string :start2 start :end2 end)) + (dlength (length delim))) + (cond ((null delim-pos) + ;; No delimiter was found. Return the rest of the string, + ;; the end of the string, and :delim-not-found. + (values (subseq string start end) end :delim-not-found)) + ((= delim-pos start) + ;; The field was empty, so return nil and skip over the delimiter. + (values nil (+ start dlength))) + ;; The following clause is subsumed by the last cond clause, + ;; and hence should probably be eliminated. +; ((= delim-pos (- end dlength)) +; ;; The delimiter is at the end of the string, so return the +; ;; field and skip to the end. +; (values (subseq string start delim-pos) +; end)) + (t + ;; The delimiter is in the middle of the string. Return the + ;; field and skip over the delimiter. + (values (subseq string start delim-pos) + (+ delim-pos dlength)))))) + +(defun parse-with-string-delimiter* (delim string &key (start 0) end + include-last) + "Breaks STRING into a list of strings, each of which was separated + from the previous by DELIM. If INCLUDE-LAST is nil (the default), + will not include the last string if it wasn't followed by DELIM + (i.e., \"foo,bar,\" vs \"foo,bar\"). Otherwise includes it even if + not terminated by DELIM. Also returns the final position in the string." + (declare (simple-string string)) + (setq end (or end (length string))) + (let (result) + (loop + (if (< start end) + (multiple-value-bind (component new-start delim-not-found) + (parse-with-string-delimiter delim string :start start :end end) + (when delim-not-found + (when include-last + (setq start new-start) + (push component result)) + (return)) + (setq start new-start) + (push component result)) + (return))) + (values (nreverse result) + start))) + +(defun get-host-string (string &optional (host-delimiter ":") (start 0) end) + "Strips the host name off the front of the string." + (setq end (or end (length string))) + (multiple-value-bind (host pos delim-not-found) + (parse-with-string-delimiter host-delimiter string :start start :end end) + (if delim-not-found + (values nil start) + (values host pos)))) + +(defun parallel-substitute (alist string) + "Makes substitutions for characters in STRING according to the ALIST. + In effect, PARALLEL-SUBSTITUTE can perform several SUBSTITUTE + operations simultaneously." + (declare (simple-string string)) + ;; This function should be generalized to arbitrary sequences and + ;; have an arglist (alist sequence &key from-end (test #'eql) test-not + ;; (start 0) (count most-positive-fixnum) end key). + (if alist + (let* ((length (length string)) + (result (make-string length))) + (declare (simple-string result)) + (dotimes (i length) + (let ((old-char (schar string i))) + (setf (schar result i) + (or (second (assoc old-char alist :test #'char=)) + old-char)))) + result) + string)) + +(defun name-substitution (alist string) + "Replaces STRING by it's replacement in ALIST, if present." + (let ((new-string (second (assoc string alist :test #'string-equal)))) + (or new-string string))) + +(unless (fboundp 'lisp::nth-value) + ;; NTH-VALUE is a CLtL2 addition, so not every lisp has it yet. + ;; This definition conses a lot, so we shouldn't use it in time-critical + ;; situations. It is fine for load-physical-hostab which is the only + ;; place we use it. + (defmacro lisp::nth-value (n form) + "Returns the nth value of the values returned by form." + `(nth ,n (multiple-value-list ,form))) + (export 'lisp::nth-value "LISP")) + +;;; ******************************** +;;; Logical Host Tables ************ +;;; ******************************** +(defvar *logical-pathname-translations-table* (make-hash-table :test #'equal)) +(defun canonicalize-logical-hostname (host) + (string-upcase host)) +(defun LOGICAL-PATHNAME-TRANSLATIONS (host) + "If HOST is the host component of a logical pathname and has been defined + as a logical pathname host name by SETF of LOGICAL-PATHNAME-TRANSLATIONS, + this function returns the list of translations for the specified HOST. + Each translation is a list of at least two elements, a from-wildname + and a to-wildname. The former is a logical pathname whose host is the + specified HOST. (I.e., the host of the from-pathname need not be + explicitly specified.) The latter is any pathname. If to-wildname coerces to + a logical pathname, TRANSLATE-LOGICAL-PATHNAME will retranslate the + result, repeatedly if necessary. Translations are listed in + the order listed, so more specific from-wildnames must precede more + general ones." + ;; would be nice to have host:: specify logical host if physical host + ;; already exists, to distinguish from host: + (gethash (canonicalize-logical-hostname host) + *logical-pathname-translations-table*)) +(defsetf logical-pathname-translations (host) (translations) + "(setf (logical-pathname-translations host) translations) sets the list + of translations for the logical pathname host to translations. If host + is a string that has not previously been used as a logical pathname + host, a new logical pathname host is defined; otherwise an existing + host's translations are replaced. Logical pathname host names are + compared with string-equal." + `(progn + (when (and *warn-about-host-type-collisions* + (physical-host-type ,host)) + (format t "~&Warning in (SETF LOGICAL-PATHNAME-TRANSLATIONS):~ + ~& ~S is defined as both a physical host and a logical host." + ,host)) + (setf (gethash (canonicalize-logical-hostname ,host) + *logical-pathname-translations-table*) + (eval-translations ,translations)))) + +;;; EVAL-TRANSLATIONS +;; +;;; Will receive a list of translations and it will evaluate the physical +;;; translation if it is not a string. This allows the user to put a format +;;; statement as the physical-translation. + +(defun eval-translations (translations) + (let (new_trans) + (nreverse + (dolist (translation translations new_trans) + (if (stringp (cadr translation)) + (setf new_trans (cons translation new_trans)) + (setf new_trans (cons (list (car translation) (eval (cadr translation))) new_trans))))))) + +;;; ******************************** +;;; Load Logical Translations ****** +;;; ******************************** +(defvar *logical-translations-directory* nil ; &&& + "Directory where logical pathname translations are stored.") +;;; (setq *logical-translations-directory* "/usr/local/lisp/Registry/") + +(defun LOAD-LOGICAL-PATHNAME-TRANSLATIONS (host) + "Loads the logical pathname translations for host named HOST if the logical + pathname translations are not already defined. First checks for a file + with the same name as the host (lowercase) and type \"translations\" in + the current directory, then the translations directory. If it finds such + a file it loads it and returns T, otherwise it signals an error." + (unless (logical-pathname-translations host) + (let* ((trans-fname (concatenate 'string (string-downcase host) + ".translations")) + (pathname (when *logical-translations-directory* + (merge-pathnames *logical-translations-directory* + trans-fname)))) + (cond ((probe-file trans-fname) + (load trans-fname) + t) + ((and *logical-translations-directory* + (probe-file pathname)) + (load pathname) + t) + (t + (error "Logical pathname translations for host ~A not found." + host)))))) + +;;; ******************************** +;;; Physical Host Tables *********** +;;; ******************************** +(defvar *physical-host-table* (make-hash-table :test #'equal) + "Table of physical hosts and system types for those hosts. + Valid (implemented) types include :vms, :explorer, :symbolics, :unix.") +(defun physical-host-type (host) + (gethash host *physical-host-table*)) +(defsetf physical-host-type (host) (type) + `(progn + (when (and *warn-about-host-type-collisions* + (logical-pathname-translations ,host)) + (format t "~&Warning in (SETF PHYSICAL-HOST-TYPE):~ + ~& ~S is defined as both a physical host and a logical host." + ,host)) + (setf (gethash ,host *physical-host-table*) + ,type))) + +(defconstant local-host-table ; &&& + #+:vms "chaos$root:[host.tables]nethosts.txt" + #-:vms "nethosts.txt") + +(defun load-physical-hostab (&optional (local-hostab local-host-table)) + "Loads the physical host namespace table. This is compatible with + vms and symbolics host tables. Hostab line format should look + something like: + HOST NAME,CHAOS-#,STATUS,SYSTEM-TYPE,MACHINE-TYPE,NICKNAMES + NAME and SYSTEM-TYPE are required; all others are optional (but delimiting + commas are still required). SYSTEM-TYPE specifies the operating system + run on the host. This information is used to figure out how to parse + pathnames for the host. Common values are: LISP, LISPM, UNIX, MACH, + VMS, and EXPLORER." + ;; What about SITE, SHORT-NAME, USER-PROPERTY, ADDRESS, PRETTY-NAME, + ;; and other Symbolics host attributes? + (when local-hostab + (with-open-file (hostab local-hostab :direction :input) + (do* ((host (read hostab nil :eof)(read hostab nil :eof)) + ;; host should be NET or HOST. + (line (read-line hostab nil :eof)(read-line hostab nil :eof))) + ;; Exit on end of file. + ((or (eq host :eof)(eq line :eof))) + ;; For each line in the host table, do + (cond ((null line) + (warn "Unexpected EOF in hostab ~S, exiting." local-hostab) + (return)) + ((string-equal (symbol-name host) "HOST") + ;; Delete spaces and tabs. + (setq line (delete #\tab (delete #\space line))) + (let ((pos 0) name system machine nicknames delim-not-found) + ;; Snarf the machine NAME. + (multiple-value-setq (name pos) + (parse-with-string-delimiter "," line :start pos)) + ;; Throw away chaos host numbers. + (setq pos + (nth-value 1 (parse-with-string-delimiter + (if (char-equal #\( (char line pos)) + ")," ",") + line :start pos))) + ;; Throw away status. + (setq pos + (nth-value 1 (parse-with-string-delimiter "," line + :start pos))) + ;; Snarf the system and machine types. + (multiple-value-setq (system pos) + (parse-with-string-delimiter "," line :start pos)) + (multiple-value-setq (machine pos delim-not-found) + (parse-with-string-delimiter "," line :start pos)) + (when (and (not delim-not-found) + (> (length line) pos)) + ;; Snarf the nicknames. + (setq nicknames + (parse-with-string-delimiter* + "," + (parse-with-string-delimiter "]" line + :start (1+ pos))))) + (unless (or (equal "" system) (null system)) + (when (equal "LISP" system) (setq system machine)) + (setq system (intern system 'keyword)) + (case system + ;; :vms, :ms-dos, etc are left alone. + ((:mach :unix :unix42) (setq system :unix)) + ((:lisp :lispm) (setq system :symbolics)) + ((:appaloosa :explorer) (setq system :explorer))) + (setf (physical-host-type name) system) + (dolist (name nicknames) + (setf (physical-host-type name) system)))))))))) + +(defun host-type (host) + "Returns the type of the host. If HOST is a defined logical pathname + host (i.e., it has translations), returns :logical. Otherwise checks + the physical type of the host. If HOST is NIL, uses the type of the + default physical host (the one lisp is running in)." + ;; Note that logical hosts have priority over physical hosts... + ;; This is a bad situation, since we don't have any way of + ;; distinguishing between host names that are both logical and physical. + ;; CLtL2 relies on the convention of naming them differently, but + ;; collisions are going to occur. It would be better to have some + ;; way of distinguishing the two in a pathname's printed representation. + (cond ((multiple-value-bind (ignore present) + (logical-pathname-translations host) + ;; Yet another use for nth-value. + (declare (ignore ignore)) + present) + :logical) + ((physical-host-type host)))) + +(defun pathname-host-type (pathname) + (cond ((typep pathname 'logical-pathname) :logical) + ((typep pathname 'pathname) + (host-type (pathname-host pathname))) + ((stringp pathname) (host-type (get-host-string pathname ":"))))) + +;;; Setup Default Physical Host +(eval-when (load eval) ; &&& +(setf (physical-host-type nil) ; nil is default host + (or #+:vms :vms + #+:explorer :explorer + #+:symbolics :symbolics + #+:unix :unix + #+:hp :unix + #+:cmu :unix + :unix ; default. change if necessary + )) +(setf (physical-host-type "Default") + (physical-host-type nil)) +) + +;;; ******************************** +;;; Translation Rules ************** +;;; ******************************** +(defstruct translation-rule + host-type + case ; Default case of pathname + char-mappings ; Character substitutions + component-mappings ; String substitutions + version-case ; Case for version component + type-case ; Case for type component + name-case ; Case for name + component-case ; Case for directory names + ) + +(defvar *permanent-translation-rules* (make-hash-table :test #'equal) + "Hash table of default translation rules for each type of host.") + +(defvar *default-translation-rule* (make-translation-rule)) + +(defmacro define-translation-rule (host-type + &key case char-mappings component-mappings + version-case + type-case + name-case + component-case) + "Defines translation rules for hosts of type host-type. + Case may be :unchanged, :upper, :lower, or :capitalize. This provides a + default case translation; version-case, type-case, name-case, and + component-case will shadow this value if non-nil. + Char-mappings is a list of character substitutions which occur in parallel. + Component-mappings is a list of string substitutions." + ;; Note: Currently there is only one rule per host-type. + `(setf (gethash ,host-type *permanent-translation-rules*) + (make-translation-rule :host-type ',host-type + :case ',case + :char-mappings ',char-mappings + :component-mappings ',component-mappings + :version-case ',version-case + :type-case ',type-case + :name-case ',name-case + :component-case ',component-case))) + +(defun find-translation-rule (host-type) + (or (gethash host-type *permanent-translation-rules*) + *default-translation-rule*)) + +(defun choose-case (rule level) + (or (case level + (version (translation-rule-version-case rule)) + (type (translation-rule-type-case rule)) + (name (translation-rule-name-case rule)) + (component (translation-rule-component-case rule))) + (translation-rule-case rule))) + +(defun casify (thing case) + (if (stringp thing) + (case case + (:upper (string-upcase thing)) + (:lower (string-downcase thing)) + (:capitalize (string-capitalize thing)) + (:unchanged thing) + (otherwise thing)) + thing)) + +(define-translation-rule :vms + :case :upper :char-mappings ((#\- #\_))) + +(define-translation-rule :unix + :case :unchanged ; :lower + :type-case :lower + ) + +(define-translation-rule :logical + :case :upper + :name-case :unchanged) + +;;; ******************************** +;;; Canonical Types **************** +;;; ******************************** +(defvar *default-canonical-types* (make-hash-table :test #'equal) + "Alists of canonical types and default surface types.") +(defvar *canonical-types-alist* (make-hash-table :test #'equal) + "Alists of canonical types and surface types for various hosts.") + +(defmacro define-canonical (level canonical default &body specs) + "Defines a new canonical type. Level specifies whether it is a + canonical type, version, name, or component. Default is a string + containing the default surface type for any kind of host not + mentioned explicitly. The body contains a list of specs that define + the surface types that indicate the new canonical type for each host. + For systems with more than one possible default surface form, + the form that appears first becomes the preferred form for the type." + `(progn + (setf (gethash ',level *default-canonical-types*) + (cons (list ',canonical ',default) + (remove ',canonical + (gethash ',level *default-canonical-types*) + :key #'car))) +; (push (list ',canonical ',default) +; (gethash ',level *default-canonical-types*)) + (setf (gethash ',level *canonical-types-alist*) + (cons (list* ',canonical ',specs) + (remove ',canonical + (gethash ',level *canonical-types-alist*) + :key #'car))) +; (push (list* ',canonical ',specs) +; (gethash ',level *canonical-types-alist*)) + )) + +(defun member-or-eq (x list-or-atom) + (cond ((listp list-or-atom) (member x list-or-atom)) + (t (eq x list-or-atom)))) + +(defun surface-form (canonical host-type &optional (level 'type)) + "Given the canonical form of some canonical type, replaces it with + the appropriate surface form." + (let ((case (choose-case (find-translation-rule host-type) level))) + (casify (or (second (assoc host-type + (cdr (assoc canonical + (gethash level + *canonical-types-alist*) + :test #'equal)) + :test #'member-or-eq)) + (second (assoc canonical + (gethash level *default-canonical-types*) + :test #'equal)) + canonical) + case))) + +(defun canonicalize (surface-form host-type &optional (level 'type)) + "Given the surface form of some canonical type, replaces it with + the appropriate canonical type." + (cond ((stringp surface-form) + (or (first (find surface-form (gethash level *canonical-types-alist*) + :key #'cdr + :test #'(lambda (surf alist) + (member surf + (cdr (assoc host-type alist + :test #'member-or-eq)) + :test #'string-equal)))) + (first (find surface-form + (gethash level *default-canonical-types*) + :key #'second :test #'string-equal)) + (coerce surface-form 'simple-string))) + (t surface-form))) + + +;;; *** Some Sample Types *** + +(define-canonical host :default "" + (:unix #+:CMU "Mach" "" "Default")) + +(define-canonical host "Default" "" + (:unix nil "" "Default")) + +(define-canonical device :unspecific "") + +(define-canonical component :absolute "" + (:unix "/") + (:symbolics ">") + (:logical "") + (:vms "")) +(define-canonical component :relative "" + (:unix "") + (:symbolics "") + (:logical ";") + (:vms ".")) +(define-canonical component :wild "*") +(define-canonical component :wild-inferiors "**" + (:vms "..")) + +(define-canonical name :wild "*") + +(define-canonical type :unspecific "") ;; null type +(define-canonical type :wild "*") ;; wild type + +;; uncommented the "L" causes the last Steele example to break, of course. +(define-canonical type :lisp "LISP" + (:unix-ucb "LISP") + (:unix #+(and :sun :kcl :unix) "lsp" + #+ecl "lsp" + "lisp" ; "L" #+:excl "cl" +) + (:vms "LSP" "LISP") + ;; (:vms4 "LSP" "LISP") + ((:tops-20 :tenex) "LISP" "LSP")) + +(define-canonical type :text "TEXT" + (:unix "text" "txt" "tx") + (:vms "TXT") + ((:tops-20 :tenex) "TXT")) + +(define-canonical type :fasl "FASL" + (:unix #+:hp "b" + #+(and :sun :kcl :unix) "o" + #+ecl "o" + #+:cmu "fasl" + "fasl" "bin" "BN") + (:vms "FAS" "BIN") + (:explorer "XLD") + (:symbolics "BIN") + ((:tops-20 :tenex) "BIN")) + +(define-canonical version :wild "*") +(define-canonical version :newest "newest") + +#| +;;; Examples: + (lp::canonicalize "*" :unix) +:WILD + (lp::surface-form :fasl :unix) +"fasl" + (lp::surface-form :fasl :vms) +"FAS" +|# + + +;;; ******************************** +;;; Pathname Defstruct ************* +;;; ******************************** +;;; +;;; We define a generic physical pathname (physical-pathname defstruct) because +;;; we have absolutely NO guarrantees about the structure of pathnames. +;;; Pathnames may be defstructs or classes, and the slots may have arbitrary +;;; types, especially with respect to the directory slot. Depending on the +;;; lisp, the directory slot may be a list, vector, simple-vector, +;;; string, keyword, or nil. If a list or vector, the items in the list +;;; may be strings, keywords (for canonical types), or nil. The first item +;;; in the list may or may not be a special keyword (e.g., :relative and +;;; :absolute). +;;; +;;; The lack of a common interface to pathnames means that any implementation +;;; of logical pathnames must parse and generate the pathname (namestring) +;;; formats for a variety of file-servers. We can't simply rely on the +;;; lisp's implementation of the PATHNAME defstruct, because that does not +;;; necessarily handle the formats of file-servers of a different type +;;; (translations may be in the format of the target file server). Also, +;;; inconsistency in the implementation of the PATHNAME type means that we +;;; would have to special case most of the code for each and every lisp. +;;; +;;; Instead, we parse the pathnames into a common format (the physical-pathname +;;; defstruct), from which we generate a namestring in a format acceptable +;;; to the underlying lisp. The namestring (which is a string in *all* the +;;; lisps) serves as the interface to the lisp's implementation of pathnames. +;;; +;;; As it currently stands, X3J13's spec for logical pathnames tries to +;;; accomplish two distinct goals: +;;; (1) isolate pathname reference from actual file location (logical +;;; as opposed to physical pathnames) +;;; (2) provide a common format for namestring syntax and +;;; pathname structure +;;; This is trying to accomplish too much within a single framework. Instead, +;;; the second goal should be decoupled from logical pathnames and made a +;;; requirement for pathnames in general. +;;; +;;; In other words, let there be a standard namestring syntax and a fully +;;; specified structure for physical pathnames (not just logical pathnames). +;;; This standard should subsume the requirements of all current lisps, and +;;; the individual lisp implementation should worry about interfacing with +;;; the file system. There is no good reason why a programmer should have +;;; to know the peculiarities of a filesystem when writing software. The X3J13 +;;; spec just shoves it under the rug, forcing the programmer to deal with +;;; it when writing the translations file. +;;; +;;; Because there is no standard for pathnames, we're forced into a situation +;;; where different lisps running on the same physical host may have +;;; different namestring syntaxes, so knowing the physical host type is not +;;; a guarrantee of the pathname syntax. +;;; +(defstruct (physical-pathname + (:conc-name %physical-pathname-) + (:predicate physical-pathnamep)) + "Physical-Pathname is the underlying structure for a pathname." + (host nil :type (or null keyword simple-string)) + (device nil :type (or null keyword simple-string)) + (directory nil :type (or null simple-vector)) + (name nil :type (or null keyword simple-string)) + (type nil :type (or null keyword simple-string)) + version) + +(defun ensure-pathname (thing) + (if (pathnamep thing) thing (pathname thing))) + +;;; ******************************** +;;; Logical Pathname Defstruct ***** +;;; ******************************** +(defstruct (logical-pathname + (:include physical-pathname) + (:conc-name %logical-pathname-) + (:print-function %print-logical-pathname) + (:constructor %make-logical-pathname + (host device directory name type version)) + (:predicate logical-pathnamep)) + "Logical-pathname is the underlying structure for a logical pathname.") + +(defun %print-logical-pathname (pname stream depth) + (declare (ignore depth)) + (format stream "#.(logical-pathname ~S)" (logical-namestring pname))) + +(defun make-logical-pathname (&key host directory name type version) + (let ((host-type (host-type host))) + (when (stringp directory) + (setq directory + (%logical-pathname-directory (parse-generic-namestring directory + host)))) + (%make-logical-pathname + (canonicalize host host-type 'host) + :unspecific + directory + (canonicalize name host-type 'name) + (canonicalize type host-type 'type) + (canonicalize version host-type 'version) + ))) + +(defun ensure-logical-pathname (thing) + (if (logical-pathnamep thing) thing (logical-pathname thing))) + +;;; The following cannot be done by the accessors because the pathname +;;; arg may be a string. + +(defun logical-pathname-host (logical-pathname) + "Returns the logical-pathname-host of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-host (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-directory (logical-pathname) + "Returns the logical-pathname-directory of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-directory (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-name (logical-pathname) + "Returns the logical-pathname-name of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-name (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-type (logical-pathname) + "Returns the logical-pathname-type of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-type (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-version (logical-pathname) + "Returns the logical-pathname-type of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-version (ensure-logical-pathname logical-pathname))) + + +;;; ******************************** +;;; Pathname Namestring Functions ** +;;; ******************************** +(defun logical-namestring (logical-pathname) + "Returns the full form of LOGICAL-PATHNAME as a string." + (setq logical-pathname (logical-pathname logical-pathname)) + (let ((host (%logical-pathname-host logical-pathname)) + (directory (%logical-pathname-directory logical-pathname)) + (name (%logical-pathname-name logical-pathname)) + (type (%logical-pathname-type logical-pathname)) + (version (%logical-pathname-version logical-pathname)) + result) + (declare (simple-string result)) + ;; FORMAT would have been easier, but this is faster. + (when host + (setq result + (concatenate 'simple-string + (surface-form host :logical 'host) ":"))) + (when directory + (setq result + (concatenate 'simple-string + result + (the simple-string (%directory-string directory))))) + (when name + (setq result + (concatenate 'simple-string + result + (the simple-string (surface-form name :logical 'name))))) + (when type + (setq result + (concatenate 'simple-string + result "." + (the simple-string (surface-form type :logical 'type))))) + (when version + (setq result + (concatenate 'simple-string + result "." + (the simple-string + (%version-to-string version))))) + result)) + +(defun %directory-string (dirlist &optional (host-type :logical) + (dir-delim #\;)) + "Converts a vector of the form #(\"foo\" \"bar\" ... \"baz\") into + a string of the form \"foo;bar;...;baz;\"" + (declare (simple-vector dirlist)) + (let* ((numdirs (length dirlist)) + (length numdirs)) + (declare (fixnum numdirs length)) + (dotimes (i numdirs) + (let ((component (#+:cmu svref #-:cmu aref dirlist i))) + (case component + ;; Do we have to worry about Lucid's :root here??? + ((:relative :absolute) + (incf length + (the fixnum + (1- (length (surface-form component + host-type 'component)))))) + (otherwise (incf length + (the fixnum + (length (surface-form component host-type + 'component)))))))) + (do ((result (make-string length)) + (index 0 (1+ index)) + (position 0)) + ((= index numdirs) result) + (declare (simple-string result)) + (let* ((component (#+:cmu svref #-:cmu aref dirlist index)) + (string (surface-form component host-type 'component)) + (len (length string)) + (end (+ position len))) + (declare (simple-string string) + (fixnum len end)) + (replace result string :start1 position :end1 end :end2 len) + (unless (or (eq component :absolute)(eq component :relative)) + (setf (schar result end) dir-delim) + (setq position (+ end 1))))))) + +(defun %version-to-string (version &optional (host-type :logical)) + (cond ((surface-form version host-type 'version)) + ((zerop version) "0") + ((eql version 1) "1") + (t + ;; Using FORMAT would have been easier, but this is faster. + (do* ((len (1+ (truncate (log version 10)))) ; base 10 num digits + (res (make-string len)) + (i (1- len) (1- i)) + (q version) ; quotient + (r)) ; residue + ((zerop q) ; nothing left + res) + (declare (simple-string res) + (fixnum len i r)) + (multiple-value-setq (q r) (truncate q 10)) + (setf (schar res i) (schar "0123456789" r)))))) + +(defun physical-namestring (pathname) + ;; needs to get appropriate surface forms + (setq pathname (pathname pathname)) + (let* ((host (%physical-pathname-host pathname)) + (host-type (host-type host)) + (device (%physical-pathname-device pathname)) + (directory (coerce (%pathname-directory pathname) 'list)) + (name (%physical-pathname-name pathname)) + (type (%physical-pathname-type pathname)) + (version (%physical-pathname-version pathname)) + (ptype (pathname-host-type pathname))) + (setq host (surface-form host host-type 'host) + name (surface-form name host-type 'name) + type (surface-form type host-type 'type) + version (surface-form version host-type 'version)) + ;; Does directory need to be mapcar'ed into surface-form? + ;; Yes, but we can probably ignore it for now, since the only + ;; canonical types defined so far are :wild and :wild-inferiors, + ;; which we don't have to support. Probably wouldn't hurt to + ;; uncomment this code. + ;;(setq directory + ;; (cons (car directory) + ;; (mapcar #'(lambda (comp) + ;; (surface-form comp host-type 'component)) + ;; (cdr directory)))) + (case ptype + (:logical + (logical-namestring pathname)) + (:unix + (format nil "~@[~A:~]~A~{~A/~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute "/") + (otherwise "")) + (cdr directory) + name type version)) + (:vms + ;; was "~@[~A:~]~@[~A:~][~A~{~A.~}]~@[~A~@[.~A~@[.~A~]~]~]" + ;; which was adding an extra "." to path + ;; such as [a.b] => [a.b.] + (format nil + "~@[~A:~]~@[~A:~][~A~{~A~^.~}]~@[~A~@[.~A~@[.~A~]~]~]" + host device (case (car directory) + (:relative ".") + (otherwise "")) + (cdr directory) + name type version)) + (:explorer + (format nil "~@[~A:~]~A~{~A~^.~};~@[~A~@[.~A~@[#~A~]~]~]" + host (case (car directory) + (:relative ".") + (otherwise "")) + (cdr directory) + name type version)) + (:symbolics + (format nil "~@[~A:~]~A~{~A>~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute ">") + (otherwise "")) + (cdr directory) + name type version)) + (otherwise + ;; Use UNIX as default. + (format nil "~@[~A:~]~A~{~A/~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute "/") + (otherwise "")) + (cdr directory) + name type version)) + ))) + +;;; ******************************** +;;; Pathname Parsing Functions ***** +;;; ******************************** +(defun logical-pathname (thing &optional host) + "Converts THING to a logical pathname and returns it. THING may be + a logical pathname, a logical pathname namestring containing a + host component, or a stream for which the pathname function returns + a logical pathname." + (etypecase thing + (string + (values (parse-generic-namestring thing host + *default-pathname-defaults* + :force-logical t))) + (pathname thing) + (logical-pathname thing) + #+:CMU(stream (logical-pathname (lisp::file-name thing) host)))) + +(defun physical-pathname (thing &optional host) + "Converts THING to a physical-pathname and returns it. THING may be + a pathname, a pathname namestring containing a + host component, or a stream for which the file-name function returns + a pathname." + (typecase thing + (string (values (parse-generic-namestring thing host))) + (logical-pathname thing) + (physical-pathname thing) + #+:CMU(stream (physical-pathname (lisp::file-name thing) host)))) + +(defun parse-generic-namestring (thing &optional host + (defaults *default-pathname-defaults*) + &key (start 0) end junk-allowed + force-logical) + "Convert namestring into a pathname." + (declare (ignore junk-allowed)) + (unless end (setf end (length thing))) + (let ((host-string (get-host-string thing ":")) + host-type) + (unless host-string (setq host-string host)) + (when (and host host-string (not (string-equal host host-string))) + (cerror "Ignore it." + "Host mismatch in ~S: ~S isn't ~S" + 'parse-generic-namestring + host-string + host)) + (if force-logical + (setq host-type :logical) + (setq host-type (host-type host-string))) + (if host-type + (multiple-value-bind (parsed-host device directory name type version) + (do-generic-pathname-parse thing host-type start end) + (let ((defaults-p (and (typep defaults 'pathname) + (equal host-type + (pathname-host-type defaults))))) + (values + (case host-type + (:logical + (make-logical-pathname + :host (or parsed-host host + (and defaults-p (logical-pathname-host defaults)) +; (when directory "Default") + ) + :directory (or directory + (and defaults-p + (logical-pathname-directory defaults))) + :name (or name + (and defaults-p + (logical-pathname-name defaults))) + :type (or type + (and defaults-p + (logical-pathname-type defaults))) + :version (or version + (and defaults-p + (logical-pathname-version defaults))))) + (otherwise + (make-pathname + :host (or parsed-host host + (and defaults-p (pathname-host defaults)) +; (when directory "Default") + ) + :device (or device + (and defaults-p + (pathname-device defaults))) + :directory (or directory + (and defaults-p + (pathname-directory defaults))) + :name (or name + (and defaults-p + (pathname-name defaults))) + :type (or type + (and defaults-p + (pathname-type defaults))) + :version (or version + (and defaults-p + (pathname-version defaults)))))) + end))) + ;; Unknown host type, wing it with parse-namestring. + (when thing + (lisp:parse-namestring thing host defaults + :start start :end end))))) + +;;; ******************************** +;;; Parse Physical Pathnames ******* +;;; ******************************** +(defun do-generic-pathname-parse (string host-type &optional (start 0) end) + "Splits string into a logical host, a vector of directories, a file name, + a file type, and a file version." + (declare (simple-string string)) + (case host-type + (:logical + ;; Parses Logical Pathnames of the following format: + ;; host:dir1;dir2;name.type.version + (parse-generic-pathname string start end ":" nil ";" "." "." ".")) + (:unix + ;; Parses Unix pathnames of the following format: + ;; host:/dir1/dir2/*/name.type.version + (parse-generic-pathname string start end ":" t "/" "." "." ".")) + (:symbolics + ;; Parses Symbolics Pathnames of the following format: + ;; host:>dir1>dir2>**>name.type.version + (parse-generic-pathname string start end ":" t ">" "." "." ".")) + (:vms (parse-vms-pathname string start end)) + (:explorer (parse-explorer-pathname string start end)) + (otherwise (warn "~&PARSE-~A-PATHNAME not yet implemented.~%" host-type) + nil))) + +(defun parse-generic-pathname (string &optional (start 0) end + (host-delim ":")(lead-is-abs t) + (dir-delim "/") + (name-delim ".")(type-delim ".") + (version-delim ".")) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses generic pathnames." + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host a-vs-r directories name type version host-type) + (multiple-value-setq (host start) + (get-host-string string host-delim start end)) + (setq host-type (host-type host)) + ;; Absolute vs. Relative + (cond ((and (not (string-equal string "" :start1 start)) + (char= (char dir-delim 0) (char string start))) + (setq a-vs-r (if lead-is-abs :absolute :relative)) + (incf start)) + (t (setq a-vs-r (if lead-is-abs :relative :absolute)))) + ;; Split off the components + (multiple-value-bind (dirs new-start) + (parse-with-string-delimiter* dir-delim string :start start :end end) + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) + (canonicalize dir host-type 'component)) + dirs)) + start new-start)) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-setq (name start) + (parse-with-string-delimiter name-delim string + :start start :end end)) + (when (< start end) + (multiple-value-setq (type start) + (parse-with-string-delimiter type-delim string + :start start :end end)) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter version-delim string + :start start :end end))))) + ;; Return the values + (values host + :unspecific + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + +(defun parse-vms-pathname (string &optional (start 0) end) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses VMS pathnames of the following formats: + host::device:[dir1.dir2...]name.type;version + host::device:name.type.version + host:device:name.type.version &c + .. = :wild-inferiors" + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host device a-vs-r (directories "") name type version) + (multiple-value-bind (new-host new-start) + (get-host-string string "::" start end) + (if new-host + (setq host new-host start new-start) + (multiple-value-setq (host start) (get-host-string string ":" start end)))) + (multiple-value-setq (device start) (get-host-string string ":" start end)) + (when (plusp (length string)) + (case (char string start) + (#\[ (multiple-value-setq (directories start) + (parse-with-string-delimiter "]" string + :start (1+ start) :end end))) + (#\< (multiple-value-setq (directories start) + (parse-with-string-delimiter ">" string + :start (1+ start) :end end))))) + ;; Absolute vs. Relative + (cond ((and (not (zerop (length directories))) + (char= #\. (char directories 0))) + (setq a-vs-r :relative)) + (t (setq a-vs-r :absolute))) + ;; Split off the components + (multiple-value-bind (dirs) + (parse-with-string-delimiter* "." directories + :start (if (eq a-vs-r :relative) 1 0) + :include-last t) ; <<< fix + (let ((last2 (when (> (length dirs) 1) + (nthcdr (- (length dirs) 2) dirs)))) + (when (equal last2 '(nil nil)) + (rplaca last2 "..") + (rplacd last2 nil))) + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) (canonicalize dir :vms 'component)) + dirs)))) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-setq (name start) + (parse-with-string-delimiter "." string :start start :end end)) + (when (< start end) + (multiple-value-bind (new-type new-start delim-not-found) + (parse-with-string-delimiter ";" string :start start :end end) + (cond (delim-not-found + (multiple-value-setq (type start) + (parse-with-string-delimiter "." string + :start start :end end))) + (t + (setq type new-type start new-start)))) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter "." string :start start :end end))))) + ;; Return the values + (values host + device + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + +(defun parse-explorer-pathname (string &optional (start 0) end) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses TI Explorer pathnames of the following format: + host:dir1.dir2...;name.type#version" + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host a-vs-r (directories "") name type version) + (multiple-value-setq (host start) + (get-host-string string ":" start end)) + (multiple-value-setq (directories start) + (parse-with-string-delimiter ";" string + :start start :end end)) + ;; Absolute vs. Relative + (cond ((and (not (zerop (length directories))) + (char= #\. (char directories 0))) + (setq a-vs-r :relative)) + (t (setq a-vs-r :absolute))) + ;; Split off the components + (multiple-value-bind (dirs) + (parse-with-string-delimiter* "." directories + :start (if (eq a-vs-r :relative) 1 0) + :end nil :include-last t) + + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) + (canonicalize dir :explorer 'component)) + dirs)))) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-bind (new-name new-start delim-not-found) + (parse-with-string-delimiter "." string :start start :end end) + (when (not delim-not-found) + (setq name new-name start new-start))) + (when (< start end) + (multiple-value-setq (type start) + (parse-with-string-delimiter "#" string :start start :end end)) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter "." string :start start :end end))))) + ;; Return the values + (values host + :unspecific + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + + +;;; ******************************** +;;; Convert Generic Pathnames ****** +;;; ******************************** +;;; Converts a generic pathname to a format for standard lisp functions. + +(defvar *translation-output* :namestring + "Specifies whether the output of translate-logical-pathname + should be a :namestring or a :pathname made with lisp:make-pathname, + or :as-is.") + +(defconstant directory-structure-type ; &&& + #+:CMU 'simple-vector + #+:lispm 'list + #+:kcl 'list + #+:ecl 'list + #+:hp 'list + #-(or :cmu :lispm :kcl :ecl :hp) + (cond ((string-equal (lisp-implementation-type) "VAX LISP") 'list) + (t 'list))) + +(defun convert-generic-pathname (pathname + &optional (output-type *translation-output*)) + (when pathname + (case output-type + (:namestring (physical-namestring pathname)) + (:pathname + (let ((host (%physical-pathname-host pathname)) + (device (%physical-pathname-device pathname)) + (directory (coerce (%physical-pathname-directory pathname) + 'list)) + (name (%physical-pathname-name pathname)) + (type (%physical-pathname-type pathname)) + (version (%physical-pathname-version pathname)) + (target-host-type (host-type nil)) + a-vs-r) + ;; Handle :absolute/:relative crap. + (setq a-vs-r (pop directory)) + (case a-vs-r + (:absolute + #+:cmu (setf device :absolute) + #+(and :sun :kcl :unix) (setq a-vs-r :root) + #+ecl (setq a-vs-r :root)) + (:relative + #+:cmu (setf device "Default"))) + ;; Reverse canonicalizations + (setq host (surface-form host target-host-type 'host) + directory (mapcar #'(lambda (dir) + (surface-form dir target-host-type + 'component)) + directory) + name (surface-form name target-host-type 'name) + type (surface-form type target-host-type 'type) + version (surface-form version target-host-type 'version)) + ;; Fixup Host + #+:cmu (setf host "Mach") + ;; Fixup Directory + #-:cmu (push a-vs-r directory) + (setq directory (coerce directory directory-structure-type)) + + (when (string-equal (lisp-implementation-type) "VAX LISP") + (setq directory + (cond ((stringp directory) directory) + ((eq (car directory) :absolute) + (format nil "[~{~A~^.~}]" (cdr directory))) + ((eq (car directory) :relative) + (format nil "[.~{~A~^.~}]" (cdr directory))) + (t (format nil "[~{~A~^.~}]" directory))))) + + ;; Return the new pathname + (make-pathname :host host :device device :directory directory + :name name :type type :version version) + )) + (otherwise pathname)))) + + +;;; ******************************** +;;; Translate Logical Pathnames **** +;;; ******************************** +(defvar *circularity-check-table* (make-hash-table :test #'equal) + "This table is used to prevent infinite circular loops in the logical + pathname resolution. If a pathname's entry in this table is set + to T, it has already been \"seen\". Seeing such a pathname twice + is an error.") + +(defun translate-logical-pathname (logical-pathname + &optional + (output-format *translation-output*)) + "Translates a logical pathname to the corresponding physical pathname. + The pathname argument is first coerced to a logical pathname [this + should really be pathname, but for that we'd have to redefine + make-pathname and friends to check whether the host is a logical host]. + If the coerced argument is a logical pathname, the first matching + translation (according to LOGICAL-PATHNAME-MATCH-P) of the logical pathname + host is applied, as if by calling TRANSLATE-LOGICAL-PATHNAME-AUX. + If the result is a logical pathname, this process is repeated. + When the result is finally a physical pathname, it is returned. If no + translation matches a logical pathname, or the resolution process loops, + an error is signaled. + + TRANSLATE-LOGICAL-PATHNAME may perform additional translations, + to provide translation of file types to local naming conventions, to + accommodate physical file systems with names of limited length, or to + deal with special character requirements such as translating hyphens + to underscores or uppercase letters to lowercase." + + ;; Ensure that it is a logical pathname + (setq logical-pathname (logical-pathname logical-pathname)) + (when (typep logical-pathname 'logical-pathname) + ;; To prevent circular loops... + (let ((namestring (logical-namestring logical-pathname))) + (setf (gethash namestring *circularity-check-table*) T)) + (unwind-protect + (resolve-logical-pathname logical-pathname output-format) + (clrhash *circularity-check-table*)))) + +(defun resolve-logical-pathname (logical-pathname + &optional + (output-format *translation-output*)) + "Resolve the logical pathname into a physical pathname using the + translations table." + (let ((logical-host (logical-pathname-host logical-pathname))) + (if logical-host + (let ((translated-pathname + (map-logical-pathname logical-pathname logical-host + output-format))) + (if translated-pathname + (or (when (eq (pathname-host-type translated-pathname) :logical) + ;; If the translation is itself a logical pathname, + ;; repeat the process until a physical pathname is reached. + (check-logical-pathname translated-pathname) + (resolve-logical-pathname translated-pathname + output-format)) + translated-pathname) + (error "No translation mapping for ~S." logical-pathname))) + (error "No such logical host in ~S:." logical-pathname)))) + +(defun check-logical-pathname (pathname) + "Ensure that there are no cycles in the translations." + (let ((namestring (logical-namestring pathname))) + (if (gethash namestring *circularity-check-table*) + (error "Circularity in translations for ~S." namestring) + (setf (gethash namestring *circularity-check-table*) T)))) + +(defun map-logical-pathname (logical-pathname + host + &optional (output-format *translation-output*)) + "Find and execute the first matching translation." + (dolist (translation (logical-pathname-translations host)) + (let ((from-pathname (logical-pathname (car translation) host)) + (to-pathname (cadr translation))) + (when (logical-pathname-match-p logical-pathname from-pathname) + (return (translate-logical-pathname-aux logical-pathname + from-pathname + to-pathname + output-format)))))) + +(defun logical-pathname-match-p (logical-pathname from-pathname) + "Return T if the logical pathname matches the test pathname." + (setq logical-pathname (logical-pathname logical-pathname) + from-pathname (logical-pathname from-pathname)) + ;; ignore host. Match directories. Match name. Match type. Match version. + (and (match-directories (logical-pathname-directory from-pathname) + (logical-pathname-directory logical-pathname)) + (match-wildcard-word (logical-pathname-name from-pathname) + (logical-pathname-name logical-pathname)) + (match-wildcard-word (logical-pathname-type from-pathname) + (logical-pathname-type logical-pathname)) + (match-wildcard-word (logical-pathname-version from-pathname) + (logical-pathname-version logical-pathname)))) + +(defun translate-logical-pathname-aux (logical-pathname + from-pathname to-pathname + &optional + (output-format *translation-output*)) + "Translates the logical pathname using the substitution specified by + a particular translation." + (let* ((host (pathname-host to-pathname)) + (host-type (host-type host)) + (translation-rule (find-translation-rule host-type)) + (char-map (translation-rule-char-mappings translation-rule)) + (string-map (translation-rule-component-mappings translation-rule))) + (let ((device (pathname-device to-pathname)) + (directories (map-directories + (pathname-directory logical-pathname) + (pathname-directory from-pathname) + (pathname-directory to-pathname) + *null-vector* 0 0 0 + (choose-case translation-rule 'component) + char-map string-map)) + (name (map-wildcard-word (pathname-name logical-pathname) + (pathname-name from-pathname) + (pathname-name to-pathname) + (choose-case translation-rule 'name) + char-map string-map)) + (type (map-wildcard-word (pathname-type logical-pathname) + (pathname-type from-pathname) + (pathname-type to-pathname) + (choose-case translation-rule 'type) + char-map string-map)) + (version (map-wildcard-word (pathname-version logical-pathname) + (pathname-version from-pathname) + (pathname-version to-pathname) + (choose-case translation-rule 'version) + char-map string-map))) + (cond ((eq (pathname-host-type to-pathname) :logical) + (make-logical-pathname :host host + :directory directories + :name name + :type type + :version version)) + (t + (convert-generic-pathname + (make-pathname :host host + :device device + :directory directories + :name name + :type type + :version version) + output-format)))))) + +;;; ******************************** +;;; Match and Map Wildcards ******** +;;; ******************************** +(defun wildcard-wordp (string) + (find #\* string)) + +(defun must-match (thing) + (or (eq thing :wild) + (and (stringp thing) + (wildcard-wordp thing)))) + +(defun match-wildcard-word (template string) + ;; "*" standalone (:wild) is treated differently from "*" within + ;; a word. + (or (eq template :wild) + (null template) + (and (stringp string) (stringp template) + (match-strings template string)) + ;; e.g., :absolute :absolute + (eq template string))) + +(defun match-strings (template string &optional (t-start 0) (s-start 0)) + (let* ((t-length (length template)) + (s-length (length string)) + (t-at-end (= t-length t-start)) + (s-at-end (= s-length s-start))) + (cond ((or t-at-end s-at-end) ; if at end of template or string + (and t-at-end s-at-end)) ; both must be at the end. + ((char= #\* (char template t-start)) + (or (match-strings template string (1+ t-start) s-start) + (match-strings template string t-start (1+ s-start)) + (match-strings template string (1+ t-start) (1+ s-start)))) + ((char-equal (char template t-start) + (char string s-start)) ; includes * against * + (match-strings template string (1+ t-start) (1+ s-start)))))) + +(defun match-directories (template dirs &optional (t-start 0) (d-start 0)) + (let* ((t-length (length template)) + (d-length (length dirs)) + (t-at-end (= t-length t-start)) + (d-at-end (= d-length d-start))) + (cond ((or t-at-end d-at-end) + (and t-at-end d-at-end)) + ((eq (#+:cmu svref #-:cmu aref template t-start) :wild-inferiors) + ;; :wild-inferiors matches any number of components, including + ;; zero. First try skipping over the :wild-inferiors. If that fails, + ;; try matching against one component without skipping over the + ;; :wild-inferiors. Finally, try matching against one component + ;; while skipping over the :wild-inferiors (the latter really + ;; isn't necessary, since the first 2 cases include it). + (or (match-directories template dirs (1+ t-start) d-start) + (match-directories template dirs t-start (1+ d-start)) + (match-directories template dirs (1+ t-start) (1+ d-start)))) + ((match-wildcard-word (#+:cmu svref #-:cmu aref template t-start) + (#+:cmu svref #-:cmu aref dirs d-start)) + (match-directories template dirs (1+ t-start) (1+ d-start)))))) + +(defun map-wildcard-word (string source target + &optional case char-mappings string-mappings) + (let ((result + (cond ((and (stringp target) + (not (wildcard-wordp target))) + ;; If the target pattern does not contain *, copy the target + ;; pattern component literally to the target instance. + target) + ((or (eq target :wild) (null target)) + ;; If the target pattern is :wild, copy the source string + ;; component to the target string literally with no further + ;; analysis. This holds even for the type, which is + ;; represented internally in terms of canonical types, + ;; and is "translated" when realized for the new host. + string) + ((not (stringp target)) + target) + ((eq source :wild) + (map-strings string string target)) + (t (map-strings string source target))))) + (when (stringp result) + (setq result + (casify (parallel-substitute char-mappings + (name-substitution string-mappings + result)) + case))) + result)) + +(defun map-strings (string source target + &optional (result "") + (s-start 0) (st-start 0) (tt-start 0)) + (let* ((s-length (length string)) + (st-length (length source)) + (tt-length (length target)) + (s-at-end (= s-length s-start)) + (st-at-end (= st-length st-start)) + (tt-at-end (= tt-length tt-start))) + (cond ((or s-at-end st-at-end) + ;; When not enough matching values are available due to too few + ;; * in the source pattern, use the null string as the matching + ;; value for any * remaining in the target. + (when (and s-at-end st-at-end) + (concatenate 'simple-string + result + (delete #\* (subseq target tt-start))))) + (tt-at-end + ;; When the source pattern has too many *, ignore the first + ;; extra * and everything following it. + result) + ((char= #\* (char target tt-start)) + ;; Replace * in target pattern with the contents of the source + ;; string specified by the next * in the source pattern. + (cond ((char= #\* (char source st-start)) + (or (map-strings string source target result + s-start (1+ st-start) (1+ tt-start)) + (map-strings string source target + (concatenate 'simple-string result + (subseq string s-start + (1+ s-start))) + (1+ s-start) st-start tt-start))) + ((char-equal (char source st-start) ; was char= + (char string s-start)) + (map-strings string source target result + (1+ s-start) (1+ st-start) tt-start)))) + (t;; copy literal strings as is from the target + (let ((next-* (position #\* target :start tt-start))) + (if next-* + (map-strings string source target + (concatenate 'simple-string result + (subseq target tt-start next-*)) + s-start st-start next-*) + (when (match-strings source string st-start s-start) + (concatenate 'simple-string + result (subseq target tt-start))))))))) + +(defun map-directories (dirs source target + &optional (result *null-vector*) + (d-start 0) (s-start 0) (t-start 0) + case char-map string-map) + (let* ((d-length (length dirs)) + (s-length (length source)) + (t-length (length target)) + (d-at-end (= d-length d-start)) + (s-at-end (= s-length s-start)) + (t-at-end (= t-length t-start))) + (cond ((or d-at-end s-at-end) + (when (and d-at-end s-at-end) + (concatenate 'simple-vector result + (map 'simple-vector + #'(lambda (x) + (map-wildcard-word + "" "" x + case char-map string-map)) + (delete :wild-inferiors + (subseq target t-start)))))) + (t-at-end + (when (match-directories source dirs s-start d-start) + result)) + ((eq :wild-inferiors (#+:cmu svref #-:cmu aref target t-start)) + (cond ((eq :wild-inferiors (#+:cmu svref + #-:cmu aref source s-start)) + (or (map-directories dirs source target result + d-start (1+ s-start) (1+ t-start) + case char-map string-map) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref + dirs d-start) + :wild :wild + case char-map + string-map))) + (1+ d-start) s-start t-start + case char-map string-map) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref + dirs d-start) + :wild :wild + case char-map + string-map))) + (1+ d-start) (1+ s-start) (1+ t-start) + case char-map string-map))) + ((string-equal (#+:cmu svref #-:cmu aref dirs d-start) + (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target result + (1+ d-start) (1+ s-start) t-start + case char-map string-map)))) + ((must-match (#+:cmu svref #-:cmu aref target t-start)) + (cond ((must-match (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref dirs d-start) + (#+:cmu svref + #-:cmu aref source s-start) + (#+:cmu svref + #-:cmu aref target t-start) + case char-map string-map))) + (1+ d-start) (1+ s-start) (1+ t-start) + case char-map string-map)) + ((string-equal (#+:cmu svref #-:cmu aref dirs d-start) + (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target result + (1+ d-start) (1+ s-start) t-start + case char-map string-map)))) + (t + (map-directories dirs source target + (concatenate 'simple-vector result + (list + (map-wildcard-word + (#+:cmu svref + #-:cmu aref target t-start) + :wild :wild + case char-map + string-map))) + d-start s-start (1+ t-start) + case char-map string-map))))) + + +;;; ******************************** +;;; Common Lisp Redefinitions ****** +;;; ******************************** +;;; Not doing merge-pathnames or with-open-file. Parse-namestring not +;;; really done well. + +;;; append-directories +(defun append-logical-directories (absolute-dir relative-dir) + (when (or absolute-dir relative-dir) + (setq absolute-dir (logical-pathname (or absolute-dir "")) + relative-dir (logical-pathname (or relative-dir ""))) + (logical-namestring + (make-logical-pathname + :host (or (logical-pathname-host absolute-dir) + (logical-pathname-host relative-dir)) + :directory (concatenate 'simple-vector + (logical-pathname-directory absolute-dir) + (cdr (coerce (logical-pathname-directory + relative-dir) + 'list))) + :name (or (logical-pathname-name absolute-dir) + (logical-pathname-name relative-dir)) + :type (or (logical-pathname-type absolute-dir) + (logical-pathname-type relative-dir)) + :version (or (logical-pathname-version absolute-dir) + (logical-pathname-version relative-dir)))))) + +(eval-when (compile load eval) +(defun real-filename (filename) + (if (and filename + (eq (pathname-host-type filename) :logical)) + (translate-logical-pathname filename :namestring) + filename)) + +#| +(defmacro convert-file-function (name &optional optionalp) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda ,(if optionalp + '(&optional filename &rest args) + '(filename &rest args)) + (apply #',old-name (real-filename filename) args)))))) +|# + +(defmacro convert-file-function (name &optional optionalp) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + ;; Yes, some lisps will give compiler warnings about OLD-name + ;; not being declared or defined as a function. But what can + ;; we do, with most lisps not yet recognizing CLtL2's ftype + ;; declaration? + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda ,(if optionalp + '(&optional filename &rest args) + '(filename &rest args)) + ,(if optionalp + `(if filename + (apply #',old-name (real-filename filename) args) + (,old-name)) ; instead of (funcall #',old-name) + `(apply #',old-name (real-filename filename) args))))))) + +(defmacro convert-file-function-2-args (name) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda (filename1 filename2 &rest args) + (apply #',old-name + (real-filename filename1)(real-filename filename2) + args)))))) +) + +(convert-file-function lisp::load) +(convert-file-function lisp::open) +(convert-file-function lisp::probe-file) +(convert-file-function lisp::delete-file) +(convert-file-function lisp::truename) +(convert-file-function lisp::directory) +(convert-file-function lisp::dribble t) +(convert-file-function lisp::ed t) +(convert-file-function lisp::file-author) +(convert-file-function lisp::file-write-date) + +(convert-file-function-2-args lisp::rename-file) +;; should take care of :output-file as well +(convert-file-function lisp::compile-file) + +(unless (fboundp 'old-parse-namestring) + (setf (symbol-function 'old-parse-namestring) + (symbol-function 'lisp::parse-namestring)) + (defun lisp::parse-namestring (thing &optional host + (defaults *default-pathname-defaults*) + &key (start 0) end junk-allowed) + "Convert THING (string, symbol, pathname, or stream) into a pathname." + (declare (ignore junk-allowed)) + (cond ((null thing) nil) ; try to fix bug with (ed). probably not here. + ((or (eq (pathname-host-type thing) :logical) + (eq (pathname-host-type defaults) :logical) + (eq (host-type host) :logical)) + ;; Tis a logical pathname + (parse-generic-namestring thing host defaults + :start start :end end)) + (t (if end + (funcall 'old-parse-namestring thing host defaults + :start start :end end) + (funcall 'old-parse-namestring thing host defaults + :start start)))))) + +;;; *EOF* diff --git a/contrib/logical-pathnames.lsp b/contrib/logical-pathnames.lsp new file mode 100644 index 000000000..b8f94624b --- /dev/null +++ b/contrib/logical-pathnames.lsp @@ -0,0 +1,2000 @@ +;;; -*- Mode: LISP; Package: LOGICAL-PATHNAME; Syntax: Common-lisp; -*- +;;; Tue Apr 9 19:17:01 1991 by Mark Kantrowitz +;;; logical-pathnames.lisp + +;;; **************************************************************** +;;; Logical Pathnames System *************************************** +;;; **************************************************************** +;;; +;;; Logical Pathnames provide a facility for referring to pathnames +;;; in a portable manner. Logical pathnames are mapped to physical +;;; pathnames by a set of implementation dependent and site-dependent +;;; rules. +;;; +;;; This system is a Common Lisp portable implementation of logical +;;; pathnames. It fulfills most of the X3J13 June 1989 specification +;;; for logical pathnames, as documented in Guy Steele's "Common Lisp: +;;; The Language" (2nd Edition), section 23.1.5 "Logical Pathnames". +;;; +;;; Written by Mark Kantrowitz, July 1990. +;;; +;;; Address: Carnegie Mellon University +;;; School of Computer Science +;;; Pittsburgh, PA 15213 +;;; +;;; This code is in the public domain and is distributed without warranty +;;; of any kind. +;;; +;;; Use and copying of this software and preparation of derivative works +;;; based upon this software are permitted, so long as the following +;;; conditions are met: +;;; o no fees or compensation are charged for use, copies, or +;;; access to this software +;;; o this copyright notice is included intact. +;;; This software is made available AS IS, and no warranty is made about +;;; the software or its performance. +;;; +;;; Please send bug reports, comments and suggestions to mkant@cs.cmu.edu. +;;; +;;; +;;; Logical Pathnames are especially useful when coupled with a portable +;;; system construction tool, such as the Defsystem facility written +;;; by Mark Kantrowitz. +;;; + +;;; ******************************** +;;; Change Log ********************* +;;; ******************************** +;;; +;;; djc = Daniel J. Clancy +;;; +;;; 30-JUL-90 mk Fixed logical pathnames for VAX-LISP (thanks to +;;; Paul Werkowski). In VAX-LISP simple strings are not +;;; sub-types of simple-vectors, so svref doesn't work +;;; on strings. These calls have been fixed to read +;;; #+:cmu svref #-:cmu aref. +;;; 15-NOV-90 mk Changed convert-file-function to better handle optional +;;; args. This should fix the problem of (ed) and (dribble) +;;; returning errors like "argument NIL must be a number" +;;; in parse-namestring. Note that some lisps seem to make +;;; a distinction between (funcall #'foo) and (foo) with +;;; respect to this error. +;;; 29-JAN-91 mk Defined LISP:NTH-VALUE if not already present (it is +;;; a CLtL2 addition) and used it in LOAD-PHYSICAL-HOSTAB +;;; to avoid needing a GARBAGE variable in +;;; (multiple-value-setq (garbage pos) ...) which we can +;;; not declare ignore and yet causes a compiler warning +;;; since we don't use it. +;;; 29-JAN-91 mk lisp::file-name is particular to CMU Common Lisp +;;; and the #+:cmu's were accidentally left off. +;;; 29-JAN-91 mk Added :explorer physical namestring output to +;;; PHYSICAL-NAMESTRING. +;;; 29-JAN-91 mk Warns about name collisions between physical and logical +;;; host names. +;;; 30-JAN-91 mk Added :logical-pathnames-mk to the *features* list. +;;; 25-FEB-91 mk Added definition of LOAD-LOGICAL-PATHNAME-TRANSLATIONS. +;;; 09-APR-91 mk Export pathname-host-type, append-logical-directories. +;;; 09-APR-91 mk Translation rules now support :case :unchanged. +;;; 09-APR-91 djc Fixed so that (logical-pathname "") returns a +;;; logical-pathname structure. +;;; 21-FEB-96 attardi +;;; Added support for ECL + +;;; ******************************** +;;; To Do ************************** +;;; ******************************** +;;; +;;; Support for Macintosh pathnames. Little tricky, since MACL uses a +;;; colon (:) as the delimiter. +;;; +;;; support for tops-20/tenex, multics, its, ms-dos +;;; add host-type to pathnames +;;; merge-pathnames, with-open-file +;;; +;;; Define generic pathname parsing/printing definition interface. +;;; +;;; Redefine with-open-file? +;;; +;;; Port to emacs-lisp for gnu-emacs? +;;; +;;; Logical pathnames needs to case both on the physical host type and on +;;; lisp type (e.g., for canonicalization). Fix this, and define lots of +;;; canonical types. Dependency on lisp type can probably be handled using +;;; #+ and #-. What about conflicts between canonicalization and the +;;; translations (e.g., "L" vs :lisp)? +;;; + +;;; ******************************** +;;; Notes ************************** +;;; ******************************** +;;; +;;; LOGICAL-PATHNAMES has been tested (successfully) in the following lisps: +;;; CMU Common Lisp (M2.9 15-Aug-90, Compiler M1.8 15-Aug-90) +;;; Macintosh Allegro Common Lisp (1.3.2) +;;; ExCL (Franz Allegro CL 3.1.12 [DEC 3100] 3/30/90) +;;; Lucid CL (Version 2.1 6-DEC-87) +;;; Symbolics Common Lisp (8.0) +;;; Lucid Common Lisp (3.0, 4.0) +;;; VAXLisp (2.0, 3.1) +;;; ECL (ECoLisp) Version(0.23) +;;; +;;; LOGICAL-PATHNAMES needs to be tested in the following lisps: +;;; KCL (June 3, 1987 or later) +;;; AKCL (1.86, June 30, 1987 or later) +;;; TI (Release 4.1 or later) +;;; Ibuki Common Lisp (01/01, October 15, 1987) +;;; Golden Common Lisp (3.1 IBM-PC) +;;; HP Common Lisp (same as Lucid?) +;;; Procyon Common Lisp + + +;;; ******************************** +;;; Documentation ****************** +;;; ******************************** +;;; +;;; Logical pathnames allow large programs to be moved between sites +;;; by separating pathname reference from actual file location. The +;;; program will refer to files using logical pathnames. At each site, +;;; a user will specify a set of "translations" which map from the logical +;;; pathnames to the physical pathnames used on the device. +;;; +;;; Logical pathnames provide a uniform convention for filesystem access, +;;; with the following properties: +;;; 1. Pathname Portability: The program specifies a pathname in +;;; a conventional format (logical pathnames), which may be +;;; mapped reasonably literally (via the translations) to +;;; a variety of filesystems. +;;; 2. Pathname Aliasing: The files may exist in different locations +;;; in the various filesystems. For example, the root directory +;;; might change. The translations allow such a change easily. +;;; 3. Cross-host Access: The files need not all exist on the same +;;; physical host. +;;; +;;; This definition of logical pathnames provides support for physical +;;; pathnames for Unix, VMS/VAX, Symbolics, and TI Explorers, and is +;;; easily extended to handle additional platforms. Code which may need +;;; customization for particular Lisps and platforms has been commented +;;; with three ampersands (&&&). In addition, the user probably should +;;; define their own canonical types, translation rules, and +;;; logical-pathname-translations. Examples are provided. +;;; +;;; Logical pathnames employ the following syntax: +;;; [host:] [;] {directory ;}* [name] [. type [. version]] +;;; host ::= word +;;; directory ::= word | wildcard-word | wildcard-inferiors +;;; name ::= word | wildcard-word +;;; type ::= word | wildcard-word +;;; version ::= word | wildcard-word +;;; word ::= {letter | digit | -}* +;;; wildcard-word ::= [word] * {word *}* [word] +;;; wildcard-inferiors ::= ** +;;; +;;; A wildcard-word of * parses as :wild; all others as strings. These +;;; definitions may be extended (e.g., "newest" parsing as :newest) by +;;; defining new canonical types. +;;; +;;; Incompatibilities with the X3J13 specification: +;;; - LOGICAL-PATHNAME is not defined as a subclass of PATHNAME +;;; since we have no guarrantee about the format of PATHNAME +;;; (i.e., is it a defstruct or a class definition, what are +;;; its slots, etc.). Many Lisps will be able to replace the +;;; definition of PHYSICAL-PATHNAME with their definition of +;;; PATHNAME by doing a string-replace of "physical-pathname" +;;; with "pathname" and deleting some definitions from this file. +;;; - CLtL does not specify the manner in which wildcards are +;;; translated. We use reversible wildcard pathname translation, +;;; similar to that used in the Symbolics logical pathnames. +;;; - COMPILE-FILE-PATHNAME has not been defined, since it is +;;; highly implementation dependent. + +;;; ******************************** +;;; Examples *********************** +;;; ******************************** +;;; +;;; The following examples of the use of logical pathnames are taken +;;; from Section 23.1.5.4 of Guy Steele CLtL 2nd Ed. + +#| +(setf (lp:physical-host-type "MY-LISPM") :symbolics) +(setf (lp:logical-pathname-translations "foo") + '(("**;*.*.*" "MY-LISPM:>library>foo>**>"))) + + (lp:translate-logical-pathname "foo:bar;baz;mum.quux.3" :namestring) +"MY-LISPM:>library>foo>bar>baz>mum.quux.3" + +(setf (lp:physical-host-type "U") :unix) +(setf (lp:physical-host-type "V") :vms) +(setf (lp:logical-pathname-translations "prog") + '(("RELEASED;*.*.*" "U:/sys/bin/my-prog/") + ("RELEASED;*;*.*.*" "U:/sys/bin/my-prog/*/") + ("EXPERIMENTAL;*.*.*" "U:/usr/Joe/development/prog/") + ("EXPERIMENTAL;DOCUMENTATION;*.*.*" "V:SYS$DISK:[JOE.DOC]") + ("EXPERIMENTAL;*;*.*.*" "U:/usr/Joe/development/prog/*/") + ("MAIL;**;*.MAIL" "V:SYS$DISK:[JOE.MAIL.PROG...]*.MBX"))) + + (lp:translate-logical-pathname "prog:mail;save;ideas.mail.3" :namestring) +"V:SYS$DISK:[JOE.MAIL.PROG.SAVE]IDEAS.MBX.3" + (lp:translate-logical-pathname "prog:experimental;spreadsheet.c" :namestring) +"U:/usr/Joe/development/prog/spreadsheet.c" + +(setf (lp:logical-pathname-translations "prog") + '(("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/documentation.lisp" + +(setf (lp:logical-pathname-translations "prog") + '(("CODE;DOCUMENTATION.*.*" "/lib/prog/docum.*") + ("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/docum.lisp" + + +(setf (lp:logical-pathname-translations "prog") + `(("**;*.LISP.*" ,(lp:logical-pathname "PROG:**;*.L.*")) + ("**;*.FASL.*" ,(lp:logical-pathname "PROG:**;*.B.*")) + ("CODE;DOCUMENTATION.*.*" "/lib/prog/documentatio.*") + ("CODE;*.*.*" "/lib/prog/"))) + (lp:translate-logical-pathname "prog:code;documentation.lisp" :namestring) +"/lib/prog/documentatio.l" + +|# + +;;; **************************************************************** +;;; Logical Pathnames ********************************************** +;;; **************************************************************** +;;; Putting this in a separate package doesn't prevent collisions +;;; with the LISP package, since this package :uses the LISP +;;; package. +(in-package "LOGICAL-PATHNAME" :nicknames '("LP")) + +(export '(logical-pathname + translate-logical-pathname + logical-pathname-translations + pathname-host-type + append-logical-directories + make-logical-pathname + physical-host-type + load-logical-pathname-translations + load-physical-hostab + define-translation-rule + define-canonical)) + +(pushnew :logical-pathnames-mk *features*) + +;;; ******************************** +;;; Global Variables *************** +;;; ******************************** +(defvar *null-vector* (coerce nil 'simple-vector)) + +(defvar *warn-about-host-type-collisions* t + "Warn user when a logical host type definition collides with a physical + host type definition.") + +;;; ******************************** +;;; Primitives ********************* +;;; ******************************** +(defun parse-with-string-delimiter (delim string &key (start 0) end) + "Returns up to three values: the string up to the delimiter DELIM + in STRING (or NIL if the field is empty), the position of the beginning + of the rest of the string after the delimiter, and a value which, if + non-NIL (:delim-not-found), specifies that the delimiter was not found." + (declare (simple-string string)) + ;; Conceivably, if DELIM is a string consisting of a single character, + ;; we could do this more efficiently using POSITION instead of SEARCH. + ;; However, any good implementation of SEARCH should optimize for that + ;; case, so nothing to worry about. + (setq end (or end (length string))) + (let ((delim-pos (search delim string :start2 start :end2 end)) + (dlength (length delim))) + (cond ((null delim-pos) + ;; No delimiter was found. Return the rest of the string, + ;; the end of the string, and :delim-not-found. + (values (subseq string start end) end :delim-not-found)) + ((= delim-pos start) + ;; The field was empty, so return nil and skip over the delimiter. + (values nil (+ start dlength))) + ;; The following clause is subsumed by the last cond clause, + ;; and hence should probably be eliminated. +; ((= delim-pos (- end dlength)) +; ;; The delimiter is at the end of the string, so return the +; ;; field and skip to the end. +; (values (subseq string start delim-pos) +; end)) + (t + ;; The delimiter is in the middle of the string. Return the + ;; field and skip over the delimiter. + (values (subseq string start delim-pos) + (+ delim-pos dlength)))))) + +(defun parse-with-string-delimiter* (delim string &key (start 0) end + include-last) + "Breaks STRING into a list of strings, each of which was separated + from the previous by DELIM. If INCLUDE-LAST is nil (the default), + will not include the last string if it wasn't followed by DELIM + (i.e., \"foo,bar,\" vs \"foo,bar\"). Otherwise includes it even if + not terminated by DELIM. Also returns the final position in the string." + (declare (simple-string string)) + (setq end (or end (length string))) + (let (result) + (loop + (if (< start end) + (multiple-value-bind (component new-start delim-not-found) + (parse-with-string-delimiter delim string :start start :end end) + (when delim-not-found + (when include-last + (setq start new-start) + (push component result)) + (return)) + (setq start new-start) + (push component result)) + (return))) + (values (nreverse result) + start))) + +(defun get-host-string (string &optional (host-delimiter ":") (start 0) end) + "Strips the host name off the front of the string." + (setq end (or end (length string))) + (multiple-value-bind (host pos delim-not-found) + (parse-with-string-delimiter host-delimiter string :start start :end end) + (if delim-not-found + (values nil start) + (values host pos)))) + +(defun parallel-substitute (alist string) + "Makes substitutions for characters in STRING according to the ALIST. + In effect, PARALLEL-SUBSTITUTE can perform several SUBSTITUTE + operations simultaneously." + (declare (simple-string string)) + ;; This function should be generalized to arbitrary sequences and + ;; have an arglist (alist sequence &key from-end (test #'eql) test-not + ;; (start 0) (count most-positive-fixnum) end key). + (if alist + (let* ((length (length string)) + (result (make-string length))) + (declare (simple-string result)) + (dotimes (i length) + (let ((old-char (schar string i))) + (setf (schar result i) + (or (second (assoc old-char alist :test #'char=)) + old-char)))) + result) + string)) + +(defun name-substitution (alist string) + "Replaces STRING by it's replacement in ALIST, if present." + (let ((new-string (second (assoc string alist :test #'string-equal)))) + (or new-string string))) + +(unless (fboundp 'lisp::nth-value) + ;; NTH-VALUE is a CLtL2 addition, so not every lisp has it yet. + ;; This definition conses a lot, so we shouldn't use it in time-critical + ;; situations. It is fine for load-physical-hostab which is the only + ;; place we use it. + (defmacro lisp::nth-value (n form) + "Returns the nth value of the values returned by form." + `(nth ,n (multiple-value-list ,form))) + (export 'lisp::nth-value "LISP")) + +;;; ******************************** +;;; Logical Host Tables ************ +;;; ******************************** +(defvar *logical-pathname-translations-table* (make-hash-table :test #'equal)) +(defun canonicalize-logical-hostname (host) + (string-upcase host)) +(defun LOGICAL-PATHNAME-TRANSLATIONS (host) + "If HOST is the host component of a logical pathname and has been defined + as a logical pathname host name by SETF of LOGICAL-PATHNAME-TRANSLATIONS, + this function returns the list of translations for the specified HOST. + Each translation is a list of at least two elements, a from-wildname + and a to-wildname. The former is a logical pathname whose host is the + specified HOST. (I.e., the host of the from-pathname need not be + explicitly specified.) The latter is any pathname. If to-wildname coerces to + a logical pathname, TRANSLATE-LOGICAL-PATHNAME will retranslate the + result, repeatedly if necessary. Translations are listed in + the order listed, so more specific from-wildnames must precede more + general ones." + ;; would be nice to have host:: specify logical host if physical host + ;; already exists, to distinguish from host: + (gethash (canonicalize-logical-hostname host) + *logical-pathname-translations-table*)) +(defsetf logical-pathname-translations (host) (translations) + "(setf (logical-pathname-translations host) translations) sets the list + of translations for the logical pathname host to translations. If host + is a string that has not previously been used as a logical pathname + host, a new logical pathname host is defined; otherwise an existing + host's translations are replaced. Logical pathname host names are + compared with string-equal." + `(progn + (when (and *warn-about-host-type-collisions* + (physical-host-type ,host)) + (format t "~&Warning in (SETF LOGICAL-PATHNAME-TRANSLATIONS):~ + ~& ~S is defined as both a physical host and a logical host." + ,host)) + (setf (gethash (canonicalize-logical-hostname ,host) + *logical-pathname-translations-table*) + (eval-translations ,translations)))) + +;;; EVAL-TRANSLATIONS +;; +;;; Will receive a list of translations and it will evaluate the physical +;;; translation if it is not a string. This allows the user to put a format +;;; statement as the physical-translation. + +(defun eval-translations (translations) + (let (new_trans) + (nreverse + (dolist (translation translations new_trans) + (if (stringp (cadr translation)) + (setf new_trans (cons translation new_trans)) + (setf new_trans (cons (list (car translation) (eval (cadr translation))) new_trans))))))) + +;;; ******************************** +;;; Load Logical Translations ****** +;;; ******************************** +(defvar *logical-translations-directory* nil ; &&& + "Directory where logical pathname translations are stored.") +;;; (setq *logical-translations-directory* "/usr/local/lisp/Registry/") + +(defun LOAD-LOGICAL-PATHNAME-TRANSLATIONS (host) + "Loads the logical pathname translations for host named HOST if the logical + pathname translations are not already defined. First checks for a file + with the same name as the host (lowercase) and type \"translations\" in + the current directory, then the translations directory. If it finds such + a file it loads it and returns T, otherwise it signals an error." + (unless (logical-pathname-translations host) + (let* ((trans-fname (concatenate 'string (string-downcase host) + ".translations")) + (pathname (when *logical-translations-directory* + (merge-pathnames *logical-translations-directory* + trans-fname)))) + (cond ((probe-file trans-fname) + (load trans-fname) + t) + ((and *logical-translations-directory* + (probe-file pathname)) + (load pathname) + t) + (t + (error "Logical pathname translations for host ~A not found." + host)))))) + +;;; ******************************** +;;; Physical Host Tables *********** +;;; ******************************** +(defvar *physical-host-table* (make-hash-table :test #'equal) + "Table of physical hosts and system types for those hosts. + Valid (implemented) types include :vms, :explorer, :symbolics, :unix.") +(defun physical-host-type (host) + (gethash host *physical-host-table*)) +(defsetf physical-host-type (host) (type) + `(progn + (when (and *warn-about-host-type-collisions* + (logical-pathname-translations ,host)) + (format t "~&Warning in (SETF PHYSICAL-HOST-TYPE):~ + ~& ~S is defined as both a physical host and a logical host." + ,host)) + (setf (gethash ,host *physical-host-table*) + ,type))) + +(defconstant local-host-table ; &&& + #+:vms "chaos$root:[host.tables]nethosts.txt" + #-:vms "nethosts.txt") + +(defun load-physical-hostab (&optional (local-hostab local-host-table)) + "Loads the physical host namespace table. This is compatible with + vms and symbolics host tables. Hostab line format should look + something like: + HOST NAME,CHAOS-#,STATUS,SYSTEM-TYPE,MACHINE-TYPE,NICKNAMES + NAME and SYSTEM-TYPE are required; all others are optional (but delimiting + commas are still required). SYSTEM-TYPE specifies the operating system + run on the host. This information is used to figure out how to parse + pathnames for the host. Common values are: LISP, LISPM, UNIX, MACH, + VMS, and EXPLORER." + ;; What about SITE, SHORT-NAME, USER-PROPERTY, ADDRESS, PRETTY-NAME, + ;; and other Symbolics host attributes? + (when local-hostab + (with-open-file (hostab local-hostab :direction :input) + (do* ((host (read hostab nil :eof)(read hostab nil :eof)) + ;; host should be NET or HOST. + (line (read-line hostab nil :eof)(read-line hostab nil :eof))) + ;; Exit on end of file. + ((or (eq host :eof)(eq line :eof))) + ;; For each line in the host table, do + (cond ((null line) + (warn "Unexpected EOF in hostab ~S, exiting." local-hostab) + (return)) + ((string-equal (symbol-name host) "HOST") + ;; Delete spaces and tabs. + (setq line (delete #\tab (delete #\space line))) + (let ((pos 0) name system machine nicknames delim-not-found) + ;; Snarf the machine NAME. + (multiple-value-setq (name pos) + (parse-with-string-delimiter "," line :start pos)) + ;; Throw away chaos host numbers. + (setq pos + (nth-value 1 (parse-with-string-delimiter + (if (char-equal #\( (char line pos)) + ")," ",") + line :start pos))) + ;; Throw away status. + (setq pos + (nth-value 1 (parse-with-string-delimiter "," line + :start pos))) + ;; Snarf the system and machine types. + (multiple-value-setq (system pos) + (parse-with-string-delimiter "," line :start pos)) + (multiple-value-setq (machine pos delim-not-found) + (parse-with-string-delimiter "," line :start pos)) + (when (and (not delim-not-found) + (> (length line) pos)) + ;; Snarf the nicknames. + (setq nicknames + (parse-with-string-delimiter* + "," + (parse-with-string-delimiter "]" line + :start (1+ pos))))) + (unless (or (equal "" system) (null system)) + (when (equal "LISP" system) (setq system machine)) + (setq system (intern system 'keyword)) + (case system + ;; :vms, :ms-dos, etc are left alone. + ((:mach :unix :unix42) (setq system :unix)) + ((:lisp :lispm) (setq system :symbolics)) + ((:appaloosa :explorer) (setq system :explorer))) + (setf (physical-host-type name) system) + (dolist (name nicknames) + (setf (physical-host-type name) system)))))))))) + +(defun host-type (host) + "Returns the type of the host. If HOST is a defined logical pathname + host (i.e., it has translations), returns :logical. Otherwise checks + the physical type of the host. If HOST is NIL, uses the type of the + default physical host (the one lisp is running in)." + ;; Note that logical hosts have priority over physical hosts... + ;; This is a bad situation, since we don't have any way of + ;; distinguishing between host names that are both logical and physical. + ;; CLtL2 relies on the convention of naming them differently, but + ;; collisions are going to occur. It would be better to have some + ;; way of distinguishing the two in a pathname's printed representation. + (cond ((multiple-value-bind (ignore present) + (logical-pathname-translations host) + ;; Yet another use for nth-value. + (declare (ignore ignore)) + present) + :logical) + ((physical-host-type host)))) + +(defun pathname-host-type (pathname) + (cond ((typep pathname 'logical-pathname) :logical) + ((typep pathname 'physical-pathname) + (host-type (physical-pathname-host pathname))) + ((stringp pathname) (host-type (get-host-string pathname ":"))))) + +;;; Setup Default Physical Host +(eval-when (load eval) ; &&& +(setf (physical-host-type nil) ; nil is default host + (or #+:vms :vms + #+:explorer :explorer + #+:symbolics :symbolics + #+:unix :unix + #+:hp :unix + #+:cmu :unix + :unix ; default. change if necessary + )) +(setf (physical-host-type "Default") + (physical-host-type nil)) +) + +;;; ******************************** +;;; Translation Rules ************** +;;; ******************************** +(defstruct translation-rule + host-type + case ; Default case of pathname + char-mappings ; Character substitutions + component-mappings ; String substitutions + version-case ; Case for version component + type-case ; Case for type component + name-case ; Case for name + component-case ; Case for directory names + ) + +(defvar *permanent-translation-rules* (make-hash-table :test #'equal) + "Hash table of default translation rules for each type of host.") + +(defvar *default-translation-rule* (make-translation-rule)) + +(defmacro define-translation-rule (host-type + &key case char-mappings component-mappings + version-case + type-case + name-case + component-case) + "Defines translation rules for hosts of type host-type. + Case may be :unchanged, :upper, :lower, or :capitalize. This provides a + default case translation; version-case, type-case, name-case, and + component-case will shadow this value if non-nil. + Char-mappings is a list of character substitutions which occur in parallel. + Component-mappings is a list of string substitutions." + ;; Note: Currently there is only one rule per host-type. + `(setf (gethash ,host-type *permanent-translation-rules*) + (make-translation-rule :host-type ',host-type + :case ',case + :char-mappings ',char-mappings + :component-mappings ',component-mappings + :version-case ',version-case + :type-case ',type-case + :name-case ',name-case + :component-case ',component-case))) + +(defun find-translation-rule (host-type) + (or (gethash host-type *permanent-translation-rules*) + *default-translation-rule*)) + +(defun choose-case (rule level) + (or (case level + (version (translation-rule-version-case rule)) + (type (translation-rule-type-case rule)) + (name (translation-rule-name-case rule)) + (component (translation-rule-component-case rule))) + (translation-rule-case rule))) + +(defun casify (thing case) + (if (stringp thing) + (case case + (:upper (string-upcase thing)) + (:lower (string-downcase thing)) + (:capitalize (string-capitalize thing)) + (:unchanged thing) + (otherwise thing)) + thing)) + +(define-translation-rule :vms + :case :upper :char-mappings ((#\- #\_))) + +(define-translation-rule :unix + :case :unchanged ; :lower + :type-case :lower + ) + +(define-translation-rule :logical + :case :upper + :name-case :unchanged) + +;;; ******************************** +;;; Canonical Types **************** +;;; ******************************** +(defvar *default-canonical-types* (make-hash-table :test #'equal) + "Alists of canonical types and default surface types.") +(defvar *canonical-types-alist* (make-hash-table :test #'equal) + "Alists of canonical types and surface types for various hosts.") + +(defmacro define-canonical (level canonical default &body specs) + "Defines a new canonical type. Level specifies whether it is a + canonical type, version, name, or component. Default is a string + containing the default surface type for any kind of host not + mentioned explicitly. The body contains a list of specs that define + the surface types that indicate the new canonical type for each host. + For systems with more than one possible default surface form, + the form that appears first becomes the preferred form for the type." + `(progn + (setf (gethash ',level *default-canonical-types*) + (cons (list ',canonical ',default) + (remove ',canonical + (gethash ',level *default-canonical-types*) + :key #'car))) +; (push (list ',canonical ',default) +; (gethash ',level *default-canonical-types*)) + (setf (gethash ',level *canonical-types-alist*) + (cons (list* ',canonical ',specs) + (remove ',canonical + (gethash ',level *canonical-types-alist*) + :key #'car))) +; (push (list* ',canonical ',specs) +; (gethash ',level *canonical-types-alist*)) + )) + +(defun member-or-eq (x list-or-atom) + (cond ((listp list-or-atom) (member x list-or-atom)) + (t (eq x list-or-atom)))) + +(defun surface-form (canonical host-type &optional (level 'type)) + "Given the canonical form of some canonical type, replaces it with + the appropriate surface form." + (let ((case (choose-case (find-translation-rule host-type) level))) + (casify (or (second (assoc host-type + (cdr (assoc canonical + (gethash level + *canonical-types-alist*) + :test #'equal)) + :test #'member-or-eq)) + (second (assoc canonical + (gethash level *default-canonical-types*) + :test #'equal)) + canonical) + case))) + +(defun canonicalize (surface-form host-type &optional (level 'type)) + "Given the surface form of some canonical type, replaces it with + the appropriate canonical type." + (cond ((stringp surface-form) + (or (first (find surface-form (gethash level *canonical-types-alist*) + :key #'cdr + :test #'(lambda (surf alist) + (member surf + (cdr (assoc host-type alist + :test #'member-or-eq)) + :test #'string-equal)))) + (first (find surface-form + (gethash level *default-canonical-types*) + :key #'second :test #'string-equal)) + (coerce surface-form 'simple-string))) + (t surface-form))) + + +;;; *** Some Sample Types *** + +(define-canonical host :default "" + (:unix #+:CMU "Mach" "" "Default")) + +(define-canonical host "Default" "" + (:unix nil "" "Default")) + +(define-canonical device :unspecific "") + +(define-canonical component :absolute "" + (:unix "/") + (:symbolics ">") + (:logical "") + (:vms "")) +(define-canonical component :relative "" + (:unix "") + (:symbolics "") + (:logical ";") + (:vms ".")) +(define-canonical component :wild "*") +(define-canonical component :wild-inferiors "**" + (:vms "..")) + +(define-canonical name :wild "*") + +(define-canonical type :unspecific "") ;; null type +(define-canonical type :wild "*") ;; wild type + +;; uncommented the "L" causes the last Steele example to break, of course. +(define-canonical type :lisp "LISP" + (:unix-ucb "LISP") + (:unix #+(and :sun :kcl :unix) "lsp" + #+ecl "lsp" + "lisp" ; "L" #+:excl "cl" +) + (:vms "LSP" "LISP") + ;; (:vms4 "LSP" "LISP") + ((:tops-20 :tenex) "LISP" "LSP")) + +(define-canonical type :text "TEXT" + (:unix "text" "txt" "tx") + (:vms "TXT") + ((:tops-20 :tenex) "TXT")) + +(define-canonical type :fasl "FASL" + (:unix #+:hp "b" + #+(and :sun :kcl :unix) "o" + #+ecl "o" + #+:cmu "fasl" + "fasl" "bin" "BN") + (:vms "FAS" "BIN") + (:explorer "XLD") + (:symbolics "BIN") + ((:tops-20 :tenex) "BIN")) + +(define-canonical version :wild "*") +(define-canonical version :newest "newest") + +#| +;;; Examples: + (lp::canonicalize "*" :unix) +:WILD + (lp::surface-form :fasl :unix) +"fasl" + (lp::surface-form :fasl :vms) +"FAS" +|# + + +;;; ******************************** +;;; Pathname Defstruct ************* +;;; ******************************** +;;; +;;; We define a generic physical pathname (physical-pathname defstruct) because +;;; we have absolutely NO guarrantees about the structure of pathnames. +;;; Pathnames may be defstructs or classes, and the slots may have arbitrary +;;; types, especially with respect to the directory slot. Depending on the +;;; lisp, the directory slot may be a list, vector, simple-vector, +;;; string, keyword, or nil. If a list or vector, the items in the list +;;; may be strings, keywords (for canonical types), or nil. The first item +;;; in the list may or may not be a special keyword (e.g., :relative and +;;; :absolute). +;;; +;;; The lack of a common interface to pathnames means that any implementation +;;; of logical pathnames must parse and generate the pathname (namestring) +;;; formats for a variety of file-servers. We can't simply rely on the +;;; lisp's implementation of the PATHNAME defstruct, because that does not +;;; necessarily handle the formats of file-servers of a different type +;;; (translations may be in the format of the target file server). Also, +;;; inconsistency in the implementation of the PATHNAME type means that we +;;; would have to special case most of the code for each and every lisp. +;;; +;;; Instead, we parse the pathnames into a common format (the physical-pathname +;;; defstruct), from which we generate a namestring in a format acceptable +;;; to the underlying lisp. The namestring (which is a string in *all* the +;;; lisps) serves as the interface to the lisp's implementation of pathnames. +;;; +;;; As it currently stands, X3J13's spec for logical pathnames tries to +;;; accomplish two distinct goals: +;;; (1) isolate pathname reference from actual file location (logical +;;; as opposed to physical pathnames) +;;; (2) provide a common format for namestring syntax and +;;; pathname structure +;;; This is trying to accomplish too much within a single framework. Instead, +;;; the second goal should be decoupled from logical pathnames and made a +;;; requirement for pathnames in general. +;;; +;;; In other words, let there be a standard namestring syntax and a fully +;;; specified structure for physical pathnames (not just logical pathnames). +;;; This standard should subsume the requirements of all current lisps, and +;;; the individual lisp implementation should worry about interfacing with +;;; the file system. There is no good reason why a programmer should have +;;; to know the peculiarities of a filesystem when writing software. The X3J13 +;;; spec just shoves it under the rug, forcing the programmer to deal with +;;; it when writing the translations file. +;;; +;;; Because there is no standard for pathnames, we're forced into a situation +;;; where different lisps running on the same physical host may have +;;; different namestring syntaxes, so knowing the physical host type is not +;;; a guarrantee of the pathname syntax. +;;; +(defstruct (physical-pathname + (:conc-name %physical-pathname-) + (:print-function %print-physical-pathname) + (:constructor %make-physical-pathname + (host device directory name type version)) + (:predicate physical-pathnamep)) + "Physical-Pathname is the underlying structure for a pathname." + (host nil :type (or null keyword simple-string)) + (device nil :type (or null keyword simple-string)) + (directory nil :type (or null simple-vector)) + (name nil :type (or null keyword simple-string)) + (type nil :type (or null keyword simple-string)) + version) + +(defun %print-physical-pathname (pname stream depth) + (declare (ignore depth)) + (format stream "#.(physical-pathname ~S)" (physical-namestring pname))) + +(defun make-physical-pathname (&key host device directory name type version) + (let ((host-type (host-type host))) + (when (stringp directory) + (setq directory + (%physical-pathname-directory (parse-generic-namestring directory + host)))) + (%make-physical-pathname + (canonicalize host host-type 'host) + (canonicalize device host-type 'device) + directory + (canonicalize name host-type 'name) + (canonicalize type host-type 'type) + (canonicalize version host-type 'version) + ))) + +(defun ensure-physical-pathname (thing) + (if (physical-pathnamep thing) thing (physical-pathname thing))) + +;;; The following cannot be done by the accessors because the pathname +;;; arg may be a string. + +(defun physical-pathname-host (pathname) + "Returns the host of PATHNAME, which may be a string or pathname." + (%physical-pathname-host (ensure-physical-pathname pathname))) + +(defun physical-pathname-device (pathname) + "Returns the device of PATHNAME, which may be a string or pathname." + (%physical-pathname-device (ensure-physical-pathname pathname))) + +(defun physical-pathname-directory (pathname) + "Returns the directory of PATHNAME, which may be a string or pathname." + (%physical-pathname-directory (ensure-physical-pathname pathname))) + +(defun physical-pathname-name (pathname) + "Returns the name of PATHNAME, which may be a string or pathname." + (%physical-pathname-name (ensure-physical-pathname pathname))) + +(defun physical-pathname-type (pathname) + "Returns the type of PATHNAME, which may be a string or pathname." + (%physical-pathname-type (ensure-physical-pathname pathname))) + +(defun physical-pathname-version (pathname) + "Returns the version of PATHNAME, which may be a string or pathname." + (%physical-pathname-version (ensure-physical-pathname pathname))) + +;;; ******************************** +;;; Logical Pathname Defstruct ***** +;;; ******************************** +(defstruct (logical-pathname + (:include physical-pathname) + (:conc-name %logical-pathname-) + (:print-function %print-logical-pathname) + (:constructor %make-logical-pathname + (host device directory name type version)) + (:predicate logical-pathnamep)) + "Logical-pathname is the underlying structure for a logical pathname.") + +(defun %print-logical-pathname (pname stream depth) + (declare (ignore depth)) + (format stream "#.(logical-pathname ~S)" (logical-namestring pname))) + +(defun make-logical-pathname (&key host directory name type version) + (let ((host-type (host-type host))) + (when (stringp directory) + (setq directory + (%logical-pathname-directory (parse-generic-namestring directory + host)))) + (%make-logical-pathname + (canonicalize host host-type 'host) + :unspecific + directory + (canonicalize name host-type 'name) + (canonicalize type host-type 'type) + (canonicalize version host-type 'version) + ))) + +(defun ensure-logical-pathname (thing) + (if (logical-pathnamep thing) thing (logical-pathname thing))) + +;;; The following cannot be done by the accessors because the pathname +;;; arg may be a string. + +(defun logical-pathname-host (logical-pathname) + "Returns the logical-pathname-host of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-host (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-directory (logical-pathname) + "Returns the logical-pathname-directory of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-directory (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-name (logical-pathname) + "Returns the logical-pathname-name of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-name (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-type (logical-pathname) + "Returns the logical-pathname-type of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-type (ensure-logical-pathname logical-pathname))) + +(defun logical-pathname-version (logical-pathname) + "Returns the logical-pathname-type of LOGICAL-PATHNAME. + LOGICAL-PATHNAME may be a string or logical pathname." + (%logical-pathname-version (ensure-logical-pathname logical-pathname))) + + +;;; ******************************** +;;; Pathname Namestring Functions ** +;;; ******************************** +(defun logical-namestring (logical-pathname) + "Returns the full form of LOGICAL-PATHNAME as a string." + (setq logical-pathname (logical-pathname logical-pathname)) + (let ((host (%logical-pathname-host logical-pathname)) + (directory (%logical-pathname-directory logical-pathname)) + (name (%logical-pathname-name logical-pathname)) + (type (%logical-pathname-type logical-pathname)) + (version (%logical-pathname-version logical-pathname)) + result) + (declare (simple-string result)) + ;; FORMAT would have been easier, but this is faster. + (when host + (setq result + (concatenate 'simple-string + (surface-form host :logical 'host) ":"))) + (when directory + (setq result + (concatenate 'simple-string + result + (the simple-string (%directory-string directory))))) + (when name + (setq result + (concatenate 'simple-string + result + (the simple-string (surface-form name :logical 'name))))) + (when type + (setq result + (concatenate 'simple-string + result "." + (the simple-string (surface-form type :logical 'type))))) + (when version + (setq result + (concatenate 'simple-string + result "." + (the simple-string + (%version-to-string version))))) + result)) + +(defun %directory-string (dirlist &optional (host-type :logical) + (dir-delim #\;)) + "Converts a vector of the form #(\"foo\" \"bar\" ... \"baz\") into + a string of the form \"foo;bar;...;baz;\"" + (declare (simple-vector dirlist)) + (let* ((numdirs (length dirlist)) + (length numdirs)) + (declare (fixnum numdirs length)) + (dotimes (i numdirs) + (let ((component (#+:cmu svref #-:cmu aref dirlist i))) + (case component + ;; Do we have to worry about Lucid's :root here??? + ((:relative :absolute) + (incf length + (the fixnum + (1- (length (surface-form component + host-type 'component)))))) + (otherwise (incf length + (the fixnum + (length (surface-form component host-type + 'component)))))))) + (do ((result (make-string length)) + (index 0 (1+ index)) + (position 0)) + ((= index numdirs) result) + (declare (simple-string result)) + (let* ((component (#+:cmu svref #-:cmu aref dirlist index)) + (string (surface-form component host-type 'component)) + (len (length string)) + (end (+ position len))) + (declare (simple-string string) + (fixnum len end)) + (replace result string :start1 position :end1 end :end2 len) + (unless (or (eq component :absolute)(eq component :relative)) + (setf (schar result end) dir-delim) + (setq position (+ end 1))))))) + +(defun %version-to-string (version &optional (host-type :logical)) + (cond ((surface-form version host-type 'version)) + ((zerop version) "0") + ((eql version 1) "1") + (t + ;; Using FORMAT would have been easier, but this is faster. + (do* ((len (1+ (truncate (log version 10)))) ; base 10 num digits + (res (make-string len)) + (i (1- len) (1- i)) + (q version) ; quotient + (r)) ; residue + ((zerop q) ; nothing left + res) + (declare (simple-string res) + (fixnum len i r)) + (multiple-value-setq (q r) (truncate q 10)) + (setf (schar res i) (schar "0123456789" r)))))) + +(defun physical-namestring (pathname) + ;; needs to get appropriate surface forms + (setq pathname (physical-pathname pathname)) + (let* ((host (%physical-pathname-host pathname)) + (host-type (host-type host)) + (device (%physical-pathname-device pathname)) + (directory (coerce (%physical-pathname-directory pathname) 'list)) + (name (%physical-pathname-name pathname)) + (type (%physical-pathname-type pathname)) + (version (%physical-pathname-version pathname)) + (ptype (pathname-host-type pathname))) + (setq host (surface-form host host-type 'host) + name (surface-form name host-type 'name) + type (surface-form type host-type 'type) + version (surface-form version host-type 'version)) + ;; Does directory need to be mapcar'ed into surface-form? + ;; Yes, but we can probably ignore it for now, since the only + ;; canonical types defined so far are :wild and :wild-inferiors, + ;; which we don't have to support. Probably wouldn't hurt to + ;; uncomment this code. + ;;(setq directory + ;; (cons (car directory) + ;; (mapcar #'(lambda (comp) + ;; (surface-form comp host-type 'component)) + ;; (cdr directory)))) + (case ptype + (:logical + (logical-namestring pathname)) + (:unix + (format nil "~@[~A:~]~A~{~A/~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute "/") + (otherwise "")) + (cdr directory) + name type version)) + (:vms + ;; was "~@[~A:~]~@[~A:~][~A~{~A.~}]~@[~A~@[.~A~@[.~A~]~]~]" + ;; which was adding an extra "." to path + ;; such as [a.b] => [a.b.] + (format nil + "~@[~A:~]~@[~A:~][~A~{~A~^.~}]~@[~A~@[.~A~@[.~A~]~]~]" + host device (case (car directory) + (:relative ".") + (otherwise "")) + (cdr directory) + name type version)) + (:explorer + (format nil "~@[~A:~]~A~{~A~^.~};~@[~A~@[.~A~@[#~A~]~]~]" + host (case (car directory) + (:relative ".") + (otherwise "")) + (cdr directory) + name type version)) + (:symbolics + (format nil "~@[~A:~]~A~{~A>~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute ">") + (otherwise "")) + (cdr directory) + name type version)) + (otherwise + ;; Use UNIX as default. + (format nil "~@[~A:~]~A~{~A/~}~@[~A~@[.~A~@[.~A~]~]~]" + host (case (car directory) + (:absolute "/") + (otherwise "")) + (cdr directory) + name type version)) + ))) + +;;; ******************************** +;;; Pathname Parsing Functions ***** +;;; ******************************** +(defun logical-pathname (thing &optional host) + "Converts THING to a logical pathname and returns it. THING may be + a logical pathname, a logical pathname namestring containing a + host component, or a stream for which the pathname function returns + a logical pathname." + (etypecase thing + (string + (values (parse-generic-namestring thing host + *default-pathname-defaults* + :force-logical t))) + (physical-pathname thing) + (logical-pathname thing) + #+:CMU(stream (logical-pathname (lisp::file-name thing) host)))) + +(defun physical-pathname (thing &optional host) + "Converts THING to a physical-pathname and returns it. THING may be + a pathname, a pathname namestring containing a + host component, or a stream for which the file-name function returns + a pathname." + (typecase thing + (string (values (parse-generic-namestring thing host))) + (logical-pathname thing) + (physical-pathname thing) + #+:CMU(stream (physical-pathname (lisp::file-name thing) host)))) + +(defun parse-generic-namestring (thing &optional host + (defaults *default-pathname-defaults*) + &key (start 0) end junk-allowed + force-logical) + "Convert namestring into a pathname." + (declare (ignore junk-allowed)) + (unless end (setf end (length thing))) + (let ((host-string (get-host-string thing ":")) + host-type) + (unless host-string (setq host-string host)) + (when (and host host-string (not (string-equal host host-string))) + (cerror "Ignore it." + "Host mismatch in ~S: ~S isn't ~S" + 'parse-generic-namestring + host-string + host)) + (if force-logical + (setq host-type :logical) + (setq host-type (host-type host-string))) + (if host-type + (multiple-value-bind (parsed-host device directory name type version) + (do-generic-pathname-parse thing host-type start end) + (let ((defaults-p (and (typep defaults 'physical-pathname) + (equal host-type + (pathname-host-type defaults))))) + (values + (case host-type + (:logical + (make-logical-pathname + :host (or parsed-host host + (and defaults-p (logical-pathname-host defaults)) +; (when directory "Default") + ) + :directory (or directory + (and defaults-p + (logical-pathname-directory defaults))) + :name (or name + (and defaults-p + (logical-pathname-name defaults))) + :type (or type + (and defaults-p + (logical-pathname-type defaults))) + :version (or version + (and defaults-p + (logical-pathname-version defaults))))) + (otherwise + (make-physical-pathname + :host (or parsed-host host + (and defaults-p (physical-pathname-host defaults)) +; (when directory "Default") + ) + :device (or device + (and defaults-p + (physical-pathname-device defaults))) + :directory (or directory + (and defaults-p + (physical-pathname-directory defaults))) + :name (or name + (and defaults-p + (physical-pathname-name defaults))) + :type (or type + (and defaults-p + (physical-pathname-type defaults))) + :version (or version + (and defaults-p + (physical-pathname-version defaults)))))) + end))) + ;; Unknown host type, wing it with parse-namestring. + (when thing + (lisp:parse-namestring thing host defaults + :start start :end end))))) + +;;; ******************************** +;;; Parse Physical Pathnames ******* +;;; ******************************** +(defun do-generic-pathname-parse (string host-type &optional (start 0) end) + "Splits string into a logical host, a vector of directories, a file name, + a file type, and a file version." + (declare (simple-string string)) + (case host-type + (:logical + ;; Parses Logical Pathnames of the following format: + ;; host:dir1;dir2;name.type.version + (parse-generic-pathname string start end ":" nil ";" "." "." ".")) + (:unix + ;; Parses Unix pathnames of the following format: + ;; host:/dir1/dir2/*/name.type.version + (parse-generic-pathname string start end ":" t "/" "." "." ".")) + (:symbolics + ;; Parses Symbolics Pathnames of the following format: + ;; host:>dir1>dir2>**>name.type.version + (parse-generic-pathname string start end ":" t ">" "." "." ".")) + (:vms (parse-vms-pathname string start end)) + (:explorer (parse-explorer-pathname string start end)) + (otherwise (warn "~&PARSE-~A-PATHNAME not yet implemented.~%" host-type) + nil))) + +(defun parse-generic-pathname (string &optional (start 0) end + (host-delim ":")(lead-is-abs t) + (dir-delim "/") + (name-delim ".")(type-delim ".") + (version-delim ".")) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses generic pathnames." + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host a-vs-r directories name type version host-type) + (multiple-value-setq (host start) + (get-host-string string host-delim start end)) + (setq host-type (host-type host)) + ;; Absolute vs. Relative + (cond ((and (not (string-equal string "" :start1 start)) + (char= (char dir-delim 0) (char string start))) + (setq a-vs-r (if lead-is-abs :absolute :relative)) + (incf start)) + (t (setq a-vs-r (if lead-is-abs :relative :absolute)))) + ;; Split off the components + (multiple-value-bind (dirs new-start) + (parse-with-string-delimiter* dir-delim string :start start :end end) + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) + (canonicalize dir host-type 'component)) + dirs)) + start new-start)) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-setq (name start) + (parse-with-string-delimiter name-delim string + :start start :end end)) + (when (< start end) + (multiple-value-setq (type start) + (parse-with-string-delimiter type-delim string + :start start :end end)) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter version-delim string + :start start :end end))))) + ;; Return the values + (values host + :unspecific + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + +(defun parse-vms-pathname (string &optional (start 0) end) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses VMS pathnames of the following formats: + host::device:[dir1.dir2...]name.type;version + host::device:name.type.version + host:device:name.type.version &c + .. = :wild-inferiors" + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host device a-vs-r (directories "") name type version) + (multiple-value-bind (new-host new-start) + (get-host-string string "::" start end) + (if new-host + (setq host new-host start new-start) + (multiple-value-setq (host start) (get-host-string string ":" start end)))) + (multiple-value-setq (device start) (get-host-string string ":" start end)) + (when (plusp (length string)) + (case (char string start) + (#\[ (multiple-value-setq (directories start) + (parse-with-string-delimiter "]" string + :start (1+ start) :end end))) + (#\< (multiple-value-setq (directories start) + (parse-with-string-delimiter ">" string + :start (1+ start) :end end))))) + ;; Absolute vs. Relative + (cond ((and (not (zerop (length directories))) + (char= #\. (char directories 0))) + (setq a-vs-r :relative)) + (t (setq a-vs-r :absolute))) + ;; Split off the components + (multiple-value-bind (dirs) + (parse-with-string-delimiter* "." directories + :start (if (eq a-vs-r :relative) 1 0) + :include-last t) ; <<< fix + (let ((last2 (when (> (length dirs) 1) + (nthcdr (- (length dirs) 2) dirs)))) + (when (equal last2 '(nil nil)) + (rplaca last2 "..") + (rplacd last2 nil))) + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) (canonicalize dir :vms 'component)) + dirs)))) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-setq (name start) + (parse-with-string-delimiter "." string :start start :end end)) + (when (< start end) + (multiple-value-bind (new-type new-start delim-not-found) + (parse-with-string-delimiter ";" string :start start :end end) + (cond (delim-not-found + (multiple-value-setq (type start) + (parse-with-string-delimiter "." string + :start start :end end))) + (t + (setq type new-type start new-start)))) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter "." string :start start :end end))))) + ;; Return the values + (values host + device + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + +(defun parse-explorer-pathname (string &optional (start 0) end) + "Splits string into a host, vector of directories, a file name, type, + and version. Parses TI Explorer pathnames of the following format: + host:dir1.dir2...;name.type#version" + (declare (simple-string string)) + (setq end (or end (length string))) + (let (host a-vs-r (directories "") name type version) + (multiple-value-setq (host start) + (get-host-string string ":" start end)) + (multiple-value-setq (directories start) + (parse-with-string-delimiter ";" string + :start start :end end)) + ;; Absolute vs. Relative + (cond ((and (not (zerop (length directories))) + (char= #\. (char directories 0))) + (setq a-vs-r :relative)) + (t (setq a-vs-r :absolute))) + ;; Split off the components + (multiple-value-bind (dirs) + (parse-with-string-delimiter* "." directories + :start (if (eq a-vs-r :relative) 1 0) + :end nil :include-last t) + + (setq directories + (cons a-vs-r + (mapcar #'(lambda (dir) + (canonicalize dir :explorer 'component)) + dirs)))) + ;; Split off the name, type, and version + (when (< start end) + (multiple-value-bind (new-name new-start delim-not-found) + (parse-with-string-delimiter "." string :start start :end end) + (when (not delim-not-found) + (setq name new-name start new-start))) + (when (< start end) + (multiple-value-setq (type start) + (parse-with-string-delimiter "#" string :start start :end end)) + (when (< start end) + (multiple-value-setq (version start) + (parse-with-string-delimiter "." string :start start :end end))))) + ;; Return the values + (values host + :unspecific + (when (or host directories) + (coerce directories 'vector)) + name + type + version + ;; This last is the remaining cruft. Should be nil. + (when (< start end) (subseq string start end))))) + + +;;; ******************************** +;;; Convert Generic Pathnames ****** +;;; ******************************** +;;; Converts a generic pathname to a format for standard lisp functions. + +(defvar *translation-output* :namestring + "Specifies whether the output of translate-logical-pathname + should be a :namestring or a :pathname made with lisp:make-pathname, + or :as-is.") + +(defconstant directory-structure-type ; &&& + #+:CMU 'simple-vector + #+:lispm 'list + #+:kcl 'list + #+:ecl 'list + #+:hp 'list + #-(or :cmu :lispm :kcl :ecl :hp) + (cond ((string-equal (lisp-implementation-type) "VAX LISP") 'list) + (t 'list))) + +(defun convert-generic-pathname (pathname + &optional (output-type *translation-output*)) + (when pathname + (case output-type + (:namestring (physical-namestring pathname)) + (:pathname + (let ((host (%physical-pathname-host pathname)) + (device (%physical-pathname-device pathname)) + (directory (coerce (%physical-pathname-directory pathname) + 'list)) + (name (%physical-pathname-name pathname)) + (type (%physical-pathname-type pathname)) + (version (%physical-pathname-version pathname)) + (target-host-type (host-type nil)) + a-vs-r) + ;; Handle :absolute/:relative crap. + (setq a-vs-r (pop directory)) + (case a-vs-r + (:absolute + #+:cmu (setf device :absolute) + #+(and :sun :kcl :unix) (setq a-vs-r :root) + #+ecl (setq a-vs-r :root)) + (:relative + #+:cmu (setf device "Default"))) + ;; Reverse canonicalizations + (setq host (surface-form host target-host-type 'host) + directory (mapcar #'(lambda (dir) + (surface-form dir target-host-type + 'component)) + directory) + name (surface-form name target-host-type 'name) + type (surface-form type target-host-type 'type) + version (surface-form version target-host-type 'version)) + ;; Fixup Host + #+:cmu (setf host "Mach") + ;; Fixup Directory + #-:cmu (push a-vs-r directory) + (setq directory (coerce directory directory-structure-type)) + + (when (string-equal (lisp-implementation-type) "VAX LISP") + (setq directory + (cond ((stringp directory) directory) + ((eq (car directory) :absolute) + (format nil "[~{~A~^.~}]" (cdr directory))) + ((eq (car directory) :relative) + (format nil "[.~{~A~^.~}]" (cdr directory))) + (t (format nil "[~{~A~^.~}]" directory))))) + + ;; Return the new pathname + (make-pathname :host host :device device :directory directory + :name name :type type :version version) + )) + (otherwise pathname)))) + + +;;; ******************************** +;;; Translate Logical Pathnames **** +;;; ******************************** +(defvar *circularity-check-table* (make-hash-table :test #'equal) + "This table is used to prevent infinite circular loops in the logical + pathname resolution. If a pathname's entry in this table is set + to T, it has already been \"seen\". Seeing such a pathname twice + is an error.") + +(defun translate-logical-pathname (logical-pathname + &optional + (output-format *translation-output*)) + "Translates a logical pathname to the corresponding physical pathname. + The pathname argument is first coerced to a logical pathname [this + should really be pathname, but for that we'd have to redefine + make-pathname and friends to check whether the host is a logical host]. + If the coerced argument is a logical pathname, the first matching + translation (according to LOGICAL-PATHNAME-MATCH-P) of the logical pathname + host is applied, as if by calling TRANSLATE-LOGICAL-PATHNAME-AUX. + If the result is a logical pathname, this process is repeated. + When the result is finally a physical pathname, it is returned. If no + translation matches a logical pathname, or the resolution process loops, + an error is signaled. + + TRANSLATE-LOGICAL-PATHNAME may perform additional translations, + to provide translation of file types to local naming conventions, to + accommodate physical file systems with names of limited length, or to + deal with special character requirements such as translating hyphens + to underscores or uppercase letters to lowercase." + + ;; Ensure that it is a logical pathname + (setq logical-pathname (logical-pathname logical-pathname)) + (when (typep logical-pathname 'logical-pathname) + ;; To prevent circular loops... + (let ((namestring (logical-namestring logical-pathname))) + (setf (gethash namestring *circularity-check-table*) T)) + (unwind-protect + (resolve-logical-pathname logical-pathname output-format) + (clrhash *circularity-check-table*)))) + +(defun resolve-logical-pathname (logical-pathname + &optional + (output-format *translation-output*)) + "Resolve the logical pathname into a physical pathname using the + translations table." + (let ((logical-host (logical-pathname-host logical-pathname))) + (if logical-host + (let ((translated-pathname + (map-logical-pathname logical-pathname logical-host + output-format))) + (if translated-pathname + (or (when (eq (pathname-host-type translated-pathname) :logical) + ;; If the translation is itself a logical pathname, + ;; repeat the process until a physical pathname is reached. + (check-logical-pathname translated-pathname) + (resolve-logical-pathname translated-pathname + output-format)) + translated-pathname) + (error "No translation mapping for ~S." logical-pathname))) + (error "No such logical host in ~S:." logical-pathname)))) + +(defun check-logical-pathname (pathname) + "Ensure that there are no cycles in the translations." + (let ((namestring (logical-namestring pathname))) + (if (gethash namestring *circularity-check-table*) + (error "Circularity in translations for ~S." namestring) + (setf (gethash namestring *circularity-check-table*) T)))) + +(defun map-logical-pathname (logical-pathname + host + &optional (output-format *translation-output*)) + "Find and execute the first matching translation." + (dolist (translation (logical-pathname-translations host)) + (let ((from-pathname (logical-pathname (car translation) host)) + (to-pathname (cadr translation))) + (when (logical-pathname-match-p logical-pathname from-pathname) + (return (translate-logical-pathname-aux logical-pathname + from-pathname + to-pathname + output-format)))))) + +(defun logical-pathname-match-p (logical-pathname from-pathname) + "Return T if the logical pathname matches the test pathname." + (setq logical-pathname (logical-pathname logical-pathname) + from-pathname (logical-pathname from-pathname)) + ;; ignore host. Match directories. Match name. Match type. Match version. + (and (match-directories (logical-pathname-directory from-pathname) + (logical-pathname-directory logical-pathname)) + (match-wildcard-word (logical-pathname-name from-pathname) + (logical-pathname-name logical-pathname)) + (match-wildcard-word (logical-pathname-type from-pathname) + (logical-pathname-type logical-pathname)) + (match-wildcard-word (logical-pathname-version from-pathname) + (logical-pathname-version logical-pathname)))) + +(defun translate-logical-pathname-aux (logical-pathname + from-pathname to-pathname + &optional + (output-format *translation-output*)) + "Translates the logical pathname using the substitution specified by + a particular translation." + (let* ((host (physical-pathname-host to-pathname)) + (host-type (host-type host)) + (translation-rule (find-translation-rule host-type)) + (char-map (translation-rule-char-mappings translation-rule)) + (string-map (translation-rule-component-mappings translation-rule))) + (let ((device (physical-pathname-device to-pathname)) + (directories (map-directories + (physical-pathname-directory logical-pathname) + (physical-pathname-directory from-pathname) + (physical-pathname-directory to-pathname) + *null-vector* 0 0 0 + (choose-case translation-rule 'component) + char-map string-map)) + (name (map-wildcard-word (physical-pathname-name logical-pathname) + (physical-pathname-name from-pathname) + (physical-pathname-name to-pathname) + (choose-case translation-rule 'name) + char-map string-map)) + (type (map-wildcard-word (physical-pathname-type logical-pathname) + (physical-pathname-type from-pathname) + (physical-pathname-type to-pathname) + (choose-case translation-rule 'type) + char-map string-map)) + (version (map-wildcard-word (physical-pathname-version logical-pathname) + (physical-pathname-version from-pathname) + (physical-pathname-version to-pathname) + (choose-case translation-rule 'version) + char-map string-map))) + (cond ((eq (pathname-host-type to-pathname) :logical) + (make-logical-pathname :host host + :directory directories + :name name + :type type + :version version)) + (t + (convert-generic-pathname + (make-physical-pathname :host host + :device device + :directory directories + :name name + :type type + :version version) + output-format)))))) + +;;; ******************************** +;;; Match and Map Wildcards ******** +;;; ******************************** +(defun wildcard-wordp (string) + (find #\* string)) + +(defun must-match (thing) + (or (eq thing :wild) + (and (stringp thing) + (wildcard-wordp thing)))) + +(defun match-wildcard-word (template string) + ;; "*" standalone (:wild) is treated differently from "*" within + ;; a word. + (or (eq template :wild) + (null template) + (and (stringp string) (stringp template) + (match-strings template string)) + ;; e.g., :absolute :absolute + (eq template string))) + +(defun match-strings (template string &optional (t-start 0) (s-start 0)) + (let* ((t-length (length template)) + (s-length (length string)) + (t-at-end (= t-length t-start)) + (s-at-end (= s-length s-start))) + (cond ((or t-at-end s-at-end) ; if at end of template or string + (and t-at-end s-at-end)) ; both must be at the end. + ((char= #\* (char template t-start)) + (or (match-strings template string (1+ t-start) s-start) + (match-strings template string t-start (1+ s-start)) + (match-strings template string (1+ t-start) (1+ s-start)))) + ((char-equal (char template t-start) + (char string s-start)) ; includes * against * + (match-strings template string (1+ t-start) (1+ s-start)))))) + +(defun match-directories (template dirs &optional (t-start 0) (d-start 0)) + (let* ((t-length (length template)) + (d-length (length dirs)) + (t-at-end (= t-length t-start)) + (d-at-end (= d-length d-start))) + (cond ((or t-at-end d-at-end) + (and t-at-end d-at-end)) + ((eq (#+:cmu svref #-:cmu aref template t-start) :wild-inferiors) + ;; :wild-inferiors matches any number of components, including + ;; zero. First try skipping over the :wild-inferiors. If that fails, + ;; try matching against one component without skipping over the + ;; :wild-inferiors. Finally, try matching against one component + ;; while skipping over the :wild-inferiors (the latter really + ;; isn't necessary, since the first 2 cases include it). + (or (match-directories template dirs (1+ t-start) d-start) + (match-directories template dirs t-start (1+ d-start)) + (match-directories template dirs (1+ t-start) (1+ d-start)))) + ((match-wildcard-word (#+:cmu svref #-:cmu aref template t-start) + (#+:cmu svref #-:cmu aref dirs d-start)) + (match-directories template dirs (1+ t-start) (1+ d-start)))))) + +(defun map-wildcard-word (string source target + &optional case char-mappings string-mappings) + (let ((result + (cond ((and (stringp target) + (not (wildcard-wordp target))) + ;; If the target pattern does not contain *, copy the target + ;; pattern component literally to the target instance. + target) + ((or (eq target :wild) (null target)) + ;; If the target pattern is :wild, copy the source string + ;; component to the target string literally with no further + ;; analysis. This holds even for the type, which is + ;; represented internally in terms of canonical types, + ;; and is "translated" when realized for the new host. + string) + ((not (stringp target)) + target) + ((eq source :wild) + (map-strings string string target)) + (t (map-strings string source target))))) + (when (stringp result) + (setq result + (casify (parallel-substitute char-mappings + (name-substitution string-mappings + result)) + case))) + result)) + +(defun map-strings (string source target + &optional (result "") + (s-start 0) (st-start 0) (tt-start 0)) + (let* ((s-length (length string)) + (st-length (length source)) + (tt-length (length target)) + (s-at-end (= s-length s-start)) + (st-at-end (= st-length st-start)) + (tt-at-end (= tt-length tt-start))) + (cond ((or s-at-end st-at-end) + ;; When not enough matching values are available due to too few + ;; * in the source pattern, use the null string as the matching + ;; value for any * remaining in the target. + (when (and s-at-end st-at-end) + (concatenate 'simple-string + result + (delete #\* (subseq target tt-start))))) + (tt-at-end + ;; When the source pattern has too many *, ignore the first + ;; extra * and everything following it. + result) + ((char= #\* (char target tt-start)) + ;; Replace * in target pattern with the contents of the source + ;; string specified by the next * in the source pattern. + (cond ((char= #\* (char source st-start)) + (or (map-strings string source target result + s-start (1+ st-start) (1+ tt-start)) + (map-strings string source target + (concatenate 'simple-string result + (subseq string s-start + (1+ s-start))) + (1+ s-start) st-start tt-start))) + ((char-equal (char source st-start) ; was char= + (char string s-start)) + (map-strings string source target result + (1+ s-start) (1+ st-start) tt-start)))) + (t;; copy literal strings as is from the target + (let ((next-* (position #\* target :start tt-start))) + (if next-* + (map-strings string source target + (concatenate 'simple-string result + (subseq target tt-start next-*)) + s-start st-start next-*) + (when (match-strings source string st-start s-start) + (concatenate 'simple-string + result (subseq target tt-start))))))))) + +(defun map-directories (dirs source target + &optional (result *null-vector*) + (d-start 0) (s-start 0) (t-start 0) + case char-map string-map) + (let* ((d-length (length dirs)) + (s-length (length source)) + (t-length (length target)) + (d-at-end (= d-length d-start)) + (s-at-end (= s-length s-start)) + (t-at-end (= t-length t-start))) + (cond ((or d-at-end s-at-end) + (when (and d-at-end s-at-end) + (concatenate 'simple-vector result + (map 'simple-vector + #'(lambda (x) + (map-wildcard-word + "" "" x + case char-map string-map)) + (delete :wild-inferiors + (subseq target t-start)))))) + (t-at-end + (when (match-directories source dirs s-start d-start) + result)) + ((eq :wild-inferiors (#+:cmu svref #-:cmu aref target t-start)) + (cond ((eq :wild-inferiors (#+:cmu svref + #-:cmu aref source s-start)) + (or (map-directories dirs source target result + d-start (1+ s-start) (1+ t-start) + case char-map string-map) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref + dirs d-start) + :wild :wild + case char-map + string-map))) + (1+ d-start) s-start t-start + case char-map string-map) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref + dirs d-start) + :wild :wild + case char-map + string-map))) + (1+ d-start) (1+ s-start) (1+ t-start) + case char-map string-map))) + ((string-equal (#+:cmu svref #-:cmu aref dirs d-start) + (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target result + (1+ d-start) (1+ s-start) t-start + case char-map string-map)))) + ((must-match (#+:cmu svref #-:cmu aref target t-start)) + (cond ((must-match (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target + (concatenate 'simple-vector result + (list (map-wildcard-word + (#+:cmu svref + #-:cmu aref dirs d-start) + (#+:cmu svref + #-:cmu aref source s-start) + (#+:cmu svref + #-:cmu aref target t-start) + case char-map string-map))) + (1+ d-start) (1+ s-start) (1+ t-start) + case char-map string-map)) + ((string-equal (#+:cmu svref #-:cmu aref dirs d-start) + (#+:cmu svref #-:cmu aref source s-start)) + (map-directories dirs source target result + (1+ d-start) (1+ s-start) t-start + case char-map string-map)))) + (t + (map-directories dirs source target + (concatenate 'simple-vector result + (list + (map-wildcard-word + (#+:cmu svref + #-:cmu aref target t-start) + :wild :wild + case char-map + string-map))) + d-start s-start (1+ t-start) + case char-map string-map))))) + + +;;; ******************************** +;;; Common Lisp Redefinitions ****** +;;; ******************************** +;;; Not doing merge-pathnames or with-open-file. Parse-namestring not +;;; really done well. + +;;; append-directories +(defun append-logical-directories (absolute-dir relative-dir) + (when (or absolute-dir relative-dir) + (setq absolute-dir (logical-pathname (or absolute-dir "")) + relative-dir (logical-pathname (or relative-dir ""))) + (logical-namestring + (make-logical-pathname + :host (or (logical-pathname-host absolute-dir) + (logical-pathname-host relative-dir)) + :directory (concatenate 'simple-vector + (logical-pathname-directory absolute-dir) + (cdr (coerce (logical-pathname-directory + relative-dir) + 'list))) + :name (or (logical-pathname-name absolute-dir) + (logical-pathname-name relative-dir)) + :type (or (logical-pathname-type absolute-dir) + (logical-pathname-type relative-dir)) + :version (or (logical-pathname-version absolute-dir) + (logical-pathname-version relative-dir)))))) + +(eval-when (compile load eval) +(defun real-filename (filename) + (if (and filename + (eq (pathname-host-type filename) :logical)) + (translate-logical-pathname filename :namestring) + filename)) + +#| +(defmacro convert-file-function (name &optional optionalp) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda ,(if optionalp + '(&optional filename &rest args) + '(filename &rest args)) + (apply #',old-name (real-filename filename) args)))))) +|# + +(defmacro convert-file-function (name &optional optionalp) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + ;; Yes, some lisps will give compiler warnings about OLD-name + ;; not being declared or defined as a function. But what can + ;; we do, with most lisps not yet recognizing CLtL2's ftype + ;; declaration? + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda ,(if optionalp + '(&optional filename &rest args) + '(filename &rest args)) + ,(if optionalp + `(if filename + (apply #',old-name (real-filename filename) args) + (,old-name)) ; instead of (funcall #',old-name) + `(apply #',old-name (real-filename filename) args))))))) + +(defmacro convert-file-function-2-args (name) + (let ((old-name (intern (concatenate 'string "OLD-" (string name))))) + `(unless (fboundp ',old-name) + (setf (symbol-function ',old-name)(symbol-function ',name)) + (setf (symbol-function ',name) + #'(lambda (filename1 filename2 &rest args) + (apply #',old-name + (real-filename filename1)(real-filename filename2) + args)))))) +) + +(convert-file-function lisp::load) +(convert-file-function lisp::open) +(convert-file-function lisp::probe-file) +(convert-file-function lisp::delete-file) +(convert-file-function lisp::truename) +(convert-file-function lisp::directory) +(convert-file-function lisp::dribble t) +(convert-file-function lisp::ed t) +(convert-file-function lisp::file-author) +(convert-file-function lisp::file-write-date) + +(convert-file-function-2-args lisp::rename-file) +;; should take care of :output-file as well +(convert-file-function lisp::compile-file) + +(unless (fboundp 'old-parse-namestring) + (setf (symbol-function 'old-parse-namestring) + (symbol-function 'lisp::parse-namestring)) + (defun lisp::parse-namestring (thing &optional host + (defaults *default-pathname-defaults*) + &key (start 0) end junk-allowed) + "Convert THING (string, symbol, pathname, or stream) into a pathname." + (declare (ignore junk-allowed)) + (cond ((null thing) nil) ; try to fix bug with (ed). probably not here. + ((or (eq (pathname-host-type thing) :logical) + (eq (pathname-host-type defaults) :logical) + (eq (host-type host) :logical)) + ;; Tis a logical pathname + (parse-generic-namestring thing host defaults + :start start :end end)) + (t (if end + (funcall 'old-parse-namestring thing host defaults + :start start :end end) + (funcall 'old-parse-namestring thing host defaults + :start start)))))) + +;;; *EOF* diff --git a/contrib/make.lsp b/contrib/make.lsp new file mode 100644 index 000000000..5843149be --- /dev/null +++ b/contrib/make.lsp @@ -0,0 +1,2730 @@ +;;; -*- Mode: LISP; Syntax: Common-Lisp -*- +;;; Wed May 22 19:33:59 1991 by Mark Kantrowitz +;;; defsystem.lisp + +;;; ******************************************************************** +;;; Portable Mini-DefSystem ******************************************** +;;; ******************************************************************** + +;;; This is a portable system definition facility for Common Lisp. +;;; Though home-grown, the syntax was inspired by fond memories of the +;;; defsystem facility on Symbolics 3600's. The exhaustive lists of +;;; filename extensions for various lisps and the idea to have one +;;; "operate-on-system" function instead of separate "compile-system" +;;; and "load-system" functions were taken from Xerox Corp.'s PCL +;;; system. + +;;; This system improves on both PCL and Symbolics defsystem utilities +;;; by performing a topological sort of the graph of file-dependency +;;; constraints. Thus, the components of the system need not be listed +;;; in any special order, because the defsystem command reorganizes them +;;; based on their constraints. It includes all the standard bells and +;;; whistles, such as not recompiling a binary file that is up to date +;;; (unless the user specifies that all files should be recompiled). + +;;; Written by Mark Kantrowitz, School of Computer Science, +;;; Carnegie Mellon University, October 1989. + +;;; Copyright (c) 1989, 1990 by Mark Kantrowitz. All rights reserved. + +;;; Use and copying of this software and preparation of derivative works +;;; based upon this software are permitted, so long as the following +;;; conditions are met: +;;; o no fees or compensation are charged for use, copies, or +;;; access to this software +;;; o this copyright notice is included intact. +;;; This software is made available AS IS, and no warranty is made about +;;; the software or its performance. + +;;; Please send bug reports, comments and suggestions to mkant@cs.cmu.edu. + +;;; ******************************** +;;; Change Log ********************* +;;; ******************************** +;;; +;;; Note: Several of the fixes from 30-JAN-91 and 31-JAN-91 were done in +;;; September and October 1990, but not documented until January 1991. +;;; +;;; sb = Sean Boisen +;;; hkt = Rick Taube +;;; brad = Brad Miller +;;; toni = Anton Beschta +;;; bw = Robert Wilhelm +;;; rs = Ralph P. Sobek +;;; gi = Gabriel Inaebnit +;;; djc = Daniel J. Clancy +;;; mc = Matthew Cornell +;;; ik = Ik Su Yoo +;;; gc = Guillaume Cartier +;;; Thanks to Steve Strassmann and +;;; Sean Boisen for detailed bug reports and +;;; miscellaneous assistance. Thanks also to Gabriel Inaebnit +;;; for help with VAXLisp bugs. +;;; +;;; 05-NOV-90 hkt Changed canonicalize-system-name to make system +;;; names package independent. Interns them in the +;;; keyword package. Thus either strings or symbols may +;;; be used to name systems from the user's point of view. +;;; 05-NOV-90 hkt Added definition FIND-SYSTEM to allow OOS to +;;; work on systems whose definition hasn't been loaded yet. +;;; 05-NOV-90 hkt Added definitions COMPILE-SYSTEM and LOAD-SYSTEM +;;; as alternates to OOS for naive users. +;;; 05-NOV-90 hkt Shadowing-import of 'defsystem in Allegro CL 3.1 [NeXT] +;;; into USER package instead of import. +;;; 15-NOV-90 mk Changed package name to "MAKE", eliminating "DEFSYSTEM" +;;; to avoid conflicts with allegro, symbolics packages +;;; named "DEFSYSTEM". +;;; 30-JAN-91 mk Modified append-directories to work with the +;;; logical-pathnames system. +;;; 30-JAN-91 mk Append-directories now works with Sun CL4.0. Also, fixed +;;; bug wrt Lucid 4.0's pathnames (which changed from lcl3.0 +;;; -- 4.0 uses a list for the directory slot, whereas +;;; 3.0 required a string). Possible fix to symbolics bug. +;;; 30-JAN-91 mk Defined NEW-REQUIRE to make redefinition of REQUIRE +;;; cleaner. Replaced all calls to REQUIRE in this file with +;;; calls to NEW-REQUIRE, which should avoid compiler warnings. +;;; 30-JAN-91 mk In VAXLisp, when we redefine lisp:require, the compiler +;;; no longer automatically executes require forms when it +;;; encounters them in a file. The user can always wrap an +;;; (eval-when (compile load eval) ...) around the require +;;; form. Alternately, see commented out code near the +;;; redefinition of lisp:require which redefines it as a +;;; macro instead. +;;; 30-JAN-91 mk Added parameter :version to operate-on-system. If it is +;;; a number, that number is used as part of the binary +;;; directory name as the place to store and load files. +;;; If NIL (the default), uses regular binary directory. +;;; If T, tries to find the most recent version of the +;;; binary directory. +;;; 30-JAN-91 mk Added global variable *use-timeouts* (default: t), which +;;; specifies whether timeouts should be used in +;;; Y-OR-N-P-WAIT. This is provided for users whose lisps +;;; don't handle read-char-no-hang properly, so that they +;;; can set it to NIL to disable the timeouts. Usually the +;;; reason for this is the lisp is run on top of UNIX, +;;; which buffers input LINES (and provides input editing). +;;; To get around this we could always turn CBREAK mode +;;; on and off, but there's no way to do this in a portable +;;; manner. +;;; 30-JAN-91 mk Fixed bug where in :test t mode it was actually providing +;;; the system, instead of faking it. +;;; 30-JAN-91 mk Changed storage of system definitions to a hash table. +;;; Changed canonicalize-system-name to coerce the system +;;; names to uppercase strings. Since we're no longer using +;;; get, there's no need to intern the names as symbols, +;;; and strings don't have packages to cause problems. +;;; Added UNDEFSYSTEM, DEFINED-SYSTEMS, and DESCRIBE-SYSTEM. +;;; Added :delete-binaries command. +;;; 31-JAN-91 mk Franz Allegro CL has a defsystem in the USER package, +;;; so we need to do a shadowing import to avoid name +;;; conflicts. +;;; 31-JAN-91 mk Fixed bug in compile-and-load-operation where it was +;;; only loading newly compiled files. +;;; 31-JAN-91 mk Added :load-time slot to components to record the +;;; file-write-date of the binary/source file that was loaded. +;;; Now knows "when" (which date version) the file was loaded. +;;; Added keyword :minimal-load and global *minimal-load* +;;; to enable defsystem to avoid reloading unmodified files. +;;; Note that if B depends on A, but A is up to date and +;;; loaded and the user specified :minimal-load T, then A +;;; will not be loaded even if B needs to be compiled. So +;;; if A is an initializations file, say, then the user should +;;; not specify :minimal-load T. +;;; 31-JAN-91 mk Added :load-only slot to components. If this slot is +;;; specified as non-NIL, skips over any attempts to compile +;;; the files in the component. (Loading the file satisfies +;;; the need to recompile.) +;;; 31-JAN-91 mk Eliminated use of set-alist-lookup and alist-lookup, +;;; replacing it with hash tables. It was too much bother, +;;; and rather brittle too. +;;; 31-JAN-91 mk Defined #@ macro character for use with AFS @sys +;;; feature simulator. #@"directory" is then synonymous +;;; with (afs-binary-directory "directory"). +;;; 31-JAN-91 mk Added :private-file type of module. It is similar to +;;; :file, but has an absolute pathname. This allows you +;;; to specify a different version of a file in a system +;;; (e.g., if you're working on the file in your home +;;; directory) without completely rewriting the system +;;; definition. +;;; 31-JAN-91 mk Operations on systems, such as :compile and :load, +;;; now propagate to subsystems the system depends on +;;; if *operations-propagate-to-subsystems* is T (the default) +;;; and the systems were defined using either defsystem +;;; or as a :system component of another system. Thus if +;;; a system depends on another, it can now recompile the +;;; other. +;;; 01-FEB-91 mk Added default definitions of PROVIDE/REQUIRE/*MODULES* +;;; for lisps that have thrown away these definitions in +;;; accordance with CLtL2. +;;; 01-FEB-91 mk Added :compile-only slot to components. Analogous to +;;; :load-only. If :compile-only is T, will not load the +;;; file on operation :compile. Either compiles or loads +;;; the file, but not both. In other words, compiling the +;;; file satisfies the demand to load it. This is useful +;;; for PCL defmethod and defclass definitions, which wrap +;;; an (eval-when (compile load eval) ...) around the body +;;; of the definition -- we save time by not loading the +;;; compiled code, since the eval-when forces it to be +;;; loaded. Note that this may not be entirely safe, since +;;; CLtL2 has added a :load keyword to compile-file, and +;;; some lisps may maintain a separate environment for +;;; the compiler. This feature is for the person who asked +;;; that a :COMPILE-SATISFIES-LOAD keyword be added to +;;; modules. It's named :COMPILE-ONLY instead to match +;;; :LOAD-ONLY. +;;; 11-FEB-91 mk Now adds :mk-defsystem to features list, to allow +;;; special cased loading of defsystem if not already +;;; present. +;;; 19-FEB-91 duff Added filename extension for hp9000/300's running Lucid. +;;; 26-FEB-91 mk Distinguish between toplevel systems (defined with +;;; defsystem) and systems defined as a :system module +;;; of a defsystem. The former can depend only on systems, +;;; while the latter can depend on anything at the same +;;; level. +;;; 12-MAR-91 mk Added :subsystem component type to be a system with +;;; pathnames relative to its parent component. +;;; 12-MAR-91 mk Uncommented :device :absolute for CMU pathnames, so +;;; that the leading slash is included. +;;; 12-MAR-91 brad Patches for Allegro 4.0.1 on Sparc. +;;; 12-MAR-91 mk Changed definition of format-justified-string so that +;;; it no longer depends on the ~<~> format directives, +;;; because Allegro 4.0.1 has a bug which doesn't support +;;; them. Anyway, the new definition is twice as fast +;;; and conses half as much as FORMAT. +;;; 12-MAR-91 toni Remove nils from list in expand-component-components. +;;; 12-MAR-91 bw If the default-package and system have the same name, +;;; and the package is not loaded, this could lead to +;;; infinite loops, so we bomb out with an error. +;;; Fixed bug in default packages. +;;; 13-MAR-91 mk Added global *providing-blocks-load-propagation* to +;;; control whether system dependencies are loaded if they +;;; have already been provided. +;;; 13-MAR-91 brad In-package is a macro in CLtL2 lisps, so we change +;;; the package manually in operate-on-component. +;;; 15-MAR-91 mk Modified *central-registry* to be either a single +;;; directory pathname, or a list of directory pathnames +;;; to be checked in order. +;;; 15-MAR-91 rs Added afs-source-directory to handle versions when +;;; compiling C code under lisp. Other minor changes to +;;; translate-version and operate-on-system. +;;; 21-MAR-91 gi Fixed bug in defined-systems. +;;; 22-MAR-91 mk Replaced append-directories with new version that works +;;; by actually appending the directories, after massaging +;;; them into the proper format. This should work for all +;;; CLtL2-compliant lisps. +;;; 09-APR-91 djc Missing package prefix for lp:pathname-host-type. +;;; Modified component-full-pathname to work for logical +;;; pathnames. +;;; 09-APR-91 mk Added *dont-redefine-require* to control whether +;;; REQUIRE is redefined. Fixed minor bugs in redefinition +;;; of require. +;;; 12-APR-91 mk (pathname-host nil) causes an error in MCL 2.0b1 +;;; 12-APR-91 mc Ported to MCL2.0b1. +;;; 16-APR-91 mk Fixed bug in needs-loading where load-time and +;;; file-write-date got swapped. +;;; 16-APR-91 mk If the component is load-only, defsystem shouldn't +;;; tell you that there is no binary and ask you if you +;;; want to load the source. +;;; 17-APR-91 mc Two additional operations for MCL. +;;; 21-APR-91 mk Added feature requested by ik. *files-missing-is-an-error* +;;; new global variable which controls whether files (source +;;; and binary) missing cause a continuable error or just a +;;; warning. +;;; 21-APR-91 mk Modified load-file-operation to allow compilation of source +;;; files during load if the binary files are old or +;;; non-existent. This adds a :compile-during-load keyword to +;;; oos, and load-system. Global *compile-during-load* sets +;;; the default (currently :query). +;;; 21-APR-91 mk Modified find-system so that there is a preference for +;;; loading system files from disk, even if the system is +;;; already defined in the environment. +;;; 25-APR-91 mk Removed load-time slot from component defstruct and added +;;; function COMPONENT-LOAD-TIME to store the load times in a +;;; hash table. This is safer than the old definition because +;;; it doesn't wipe out load times every time the system is +;;; redefined. +;;; 25-APR-91 mk Completely rewrote load-file-operation. Fixed some bugs +;;; in :compile-during-load and in the behavior of defsystem +;;; when multiple users are compiling and loading a system +;;; instead of just a single user. +;;; 16-MAY-91 mk Modified FIND-SYSTEM to do the right thing if the system +;;; definition file cannot be found. +;;; 16-MAY-91 mk Added globals *source-pathname-default* and +;;; *binary-pathname-default* to contain default values for +;;; :source-pathname and :binary-pathname. For example, set +;;; *source-pathname-default* to "" to avoid having to type +;;; :source-pathname "" all the time. +;;; 27-MAY-91 mk Fixed bug in new-append-directories where directory +;;; components of the form "foo4.0" would appear as "foo4", +;;; since pathname-name truncates the type. Changed +;;; pathname-name to file-namestring. +;;; 3-JUN-91 gc Small bug in new-append-directories; replace (when +;;; abs-name) with (when (not (null-string abs-name))) +;;; 4-JUN-91 mk Additional small change to new-append-directories for +;;; getting the device from the relative pname if the abs +;;; pname is "". This is to fix a small behavior in CMU CL old +;;; compiler. Also changed (when (not (null-string abs-name))) +;;; to have an (and abs-name) in there. +;;; 8-JAN-92 sb Added filename extension for defsystem under Lucid Common +;;; Lisp/SGO 3.0.1+. +;;; 8-JAN-92 mk Changed the definition of prompt-string to work around an +;;; AKCL bug. Essentially, AKCL doesn't default the colinc to +;;; 1 if the colnum is provided, so we hard code it. +;;; 8-JAN-92 rs (pathname-directory (pathname "")) returns '(:relative) in +;;; Lucid, instead of NIL. Changed new-append-directories and +;;; test-new-append-directories to reflect this. +;;; 8-JAN-92 mk Fixed problem related to *load-source-if-no-binary*. +;;; compile-and-load-source-if-no-binary wasn't checking for +;;; the existence of the binary if this variable was true, +;;; causing the file to not be compiled. +;;; 8-JAN-92 mk Fixed problem with null-string being called on a pathname. + + + +;;; ******************************** +;;; To Do ************************** +;;; ******************************** +;;; +;;; Need way to load old binaries even if source is newer. +;;; +;;; Load a system (while not loading anything already loaded) +;;; and inform the user of out of date fasls with the choice +;;; to load the old fasl or recompile and then load the new +;;; fasl? +;;; +;;; modify compile-file-operation to handle a query keyword.... +;;; +;;; Perhaps systems should keep around the file-write-date of the system +;;; definition file, to prevent excessive reloading of the system definition? +;;; +;;; load-file-operation needs to be completely reworked to simplify the +;;; logic of when files get loaded or not. +;;; +;;; Need to revamp output: Nesting and indenting verbose output doesn't +;;; seem cool, especially when output overflows the 80-column margins. +;;; +;;; Document various ways of writing a system. simple (short) form +;;; (where :components is just a list of filenames) in addition to verbose. +;;; Put documentation strings in code. +;;; +;;; :load-time for modules and systems -- maybe record the time the system +;;; was loaded/compiled here and print it in describe-system? +;;; +;;; Make it easy to define new functions that operate on a system. For +;;; example, a function that prints out a list of files that have changed, +;;; hardcopy-system, edit-system, etc. +;;; +;;; If a user wants to have identical systems for different lisps, do we +;;; force the user to use logical pathnames? Or maybe we should write a +;;; generic-pathnames package that parses any pathname format into a +;;; uniform underlying format (i.e., pull the relevant code out of +;;; logical-pathnames.lisp and clean it up a bit). +;;; +;;; Verify that Mac pathnames now work with append-directories. +;;; +;;; A common human error is to violate the modularization by making a file +;;; in one module depend on a file in another module, instead of making +;;; one module depend on the other. This is caught because the dependency +;;; isn't found. However, is there any way to provide a more informative +;;; error message? Probably not, especially if the system has multiple +;;; files of the same name. +;;; +;;; For a module none of whose files needed to be compiled, have it print out +;;; "no files need recompilation". +;;; +;;; Write a system date/time to a file? (version information) I.e., if the +;;; filesystem supports file version numbers, write an auxiliary file to +;;; the system definition file that specifies versions of the system and +;;; the version numbers of the associated files. +;;; +;;; Add idea of a patch directory. +;;; +;;; In verbose printout, have it log a date/time at start and end of +;;; compilation: +;;; Compiling system "test" on 31-Jan-91 21:46:47 +;;; by Defsystem version v2.0 01-FEB-91. +;;; +;;; Define other :force options: +;;; :query allows user to specify that a file not normally compiled +;;; should be. OR +;;; :confirm allows user to specify that a file normally compiled +;;; shouldn't be. AND +;;; +;;; We currently assume that compilation-load dependencies and if-changed +;;; dependencies are identical. However, in some cases this might not be +;;; true. For example, if we change a macro we have to recompile functions +;;; that depend on it (except in lisps that automatically do this, such +;;; as the new CMU Common Lisp), but not if we change a function. Splitting +;;; these apart (with appropriate defaulting) would be nice, but not worth +;;; doing immediately since it may save only a couple of file recompilations, +;;; while making defsystem much more complex than it already is. +;;; + +;;; ******************************** +;;; Notes ************************** +;;; ******************************** +;;; +;;; DEFSYSTEM has been tested (successfully) in the following lisps: +;;; CMU Common Lisp (M2.9 15-Aug-90, Compiler M1.8 15-Aug-90) +;;; CMU Common Lisp (14-Dec-90 beta, Python Compiler 0.0 PMAX/Mach) +;;; ExCL (Franz Allegro CL 3.1.12 [DEC 3100] 3/30/90) +;;; ExCL (Franz Allegro CL 4.0.1 [SPARC]) +;;; Lucid CL (Version 2.1 6-DEC-87) +;;; Lucid Common Lisp (3.0 [SPARC,SUN3]) +;;; Lucid Common Lisp (4.0 [SPARC,SUN3]) +;;; VAXLisp (v2.2) [VAX/VMS] +;;; VAXLisp (v3.1) +;;; +;;; DEFSYSTEM needs to be tested in the following lisps: +;;; Symbolics Common Lisp (8.0) +;;; Macintosh Allegro Common Lisp (1.3.2) +;;; KCL (June 3, 1987 or later) +;;; AKCL (1.86, June 30, 1987 or later) +;;; TI (Release 4.1 or later) +;;; Ibuki Common Lisp (01/01, October 15, 1987) +;;; Golden Common Lisp (3.1 IBM-PC) +;;; HP Common Lisp (same as Lucid?) +;;; Procyon Common Lisp + + +;;; ******************************************************************** +;;; How to Use this System ********************************************* +;;; ******************************************************************** + +;;; To use this system, +;;; 1. If you want to have a central registry of system definitions, +;;; modify the value of the variable *central-registry* below. +;;; 2. Load this file (defsystem.lisp) in either source or compiled form, +;;; 3. Load the file containing the "defsystem" definition of your system, +;;; 4. Use the function "operate-on-system" to do things to your system. + +;;; For more information, see the documentation and examples in +;;; lisp-utilities.ps. + +;;; **************************************************************** +;;; Lisp Code ****************************************************** +;;; **************************************************************** + +;;; ******************************** +;;; Massage CLtL2 onto *features* ** +;;; ******************************** +;;; Let's be smart about CLtL2 compatible Lisps: +(eval-when (compile load eval) + #+(or (and :excl :allegro-v4.0) :mcl) + (pushnew :cltl2 *features*)) + +;;; ******************************** +;;; Provide/Require/*modules* ****** +;;; ******************************** + +;;; Since CLtL2 has dropped require and provide from the language, some +;;; lisps may not have the functions PROVIDE and REQUIRE and the +;;; global *MODULES*. So if lisp::provide and user::provide are not +;;; defined, we define our own. + +;;; Hmmm. CMU CL old compiler gives bogus warnings here about functions +;;; and variables not being declared or bound, apparently because it +;;; sees that (or (fboundp 'lisp::require) (fboundp 'user::require)) returns +;;; T, so it doesn't really bother when compiling the body of the unless. +;;; The new compiler does this properly, so I'm not going to bother +;;; working around this. + +;;; KCL (and derivatives) complain about the following in-package, proved, +;;; export and import forms being "in a bad place" if any non-package related +;;; form preceeds it. So I moved them before all the other stuff and skip +;;; the following conditional which is unnecessary in KCL anyway. +;;; -- stolcke 10/22/93 + +#-(or (and :CMU (not :new-compiler)) :vms :mcl :kcl :ECL) +(eval-when (compile load eval) + (unless (or (fboundp 'lisp::require) (fboundp 'user::require) + #+(and :excl :allegro-v4.0) (fboundp 'cltl1::require)) + (in-package "LISP") + (export '(*modules* provide require)) + + ;; Documentation strings taken almost literally from CLtL1. + + (defvar *MODULES* () + "List of names of the modules that have been loaded into Lisp so far. + It is used by PROVIDE and REQUIRE.") + + ;; We provide two different ways to define modules. The default way + ;; is to put either a source or binary file with the same name + ;; as the module in the library directory. The other way is to define + ;; the list of files in the module with defmodule. + + ;; The directory listed in *library* is implementation dependent, + ;; and is intended to be used by Lisp manufacturers as a place to + ;; store their implementation dependent packages. + ;; Lisp users should use systems and *central-registry* to store + ;; their packages -- it is intended that *central-registry* is + ;; set by the user, while *library* is set by the lisp. + + (defvar *library* nil ; "/usr/local/lisp/Modules/" + "Directory within the file system containing files, where the name + of a file is the same as the name of the module it contains.") + + (defun canonicalize-module-name (name) + ;; if symbol, string-downcase the printrep to make nicer filenames. + (if (stringp name) name (string-downcase (string name)))) + + (defvar *module-files* (make-hash-table :test #'equal) + "Hash table mapping from module names to list of files for the + module. REQUIRE loads these files in order.") + (defmacro defmodule (name &rest files) + "Defines a module NAME to load the specified FILES in order." + `(setf (gethash (canonicalize-module-name ,name) *module-files*) + ',files)) + (defun module-files (name) + (gethash name *module-files*)) + + (defun PROVIDE (name) + "Adds a new module name to the list of modules maintained in the + variable *modules*, thereby indicating that the module has been + loaded. Name may be a string or symbol -- strings are case-senstive, + while symbols are treated like lowercase strings. Returns T if + NAME was not already present, NIL otherwise." + (let ((module (canonicalize-module-name name))) + (unless (find module *modules* :test #'string=) + ;; Module not present. Add it and return T to signify that it + ;; was added. + (push module *modules*) + t))) + + (defun REQUIRE (name &optional pathname) + "Tests whether a module is already present. If the module is not + present, loads the appropriate file or set of files. The pathname + argument, if present, is a single pathname or list of pathnames + whose files are to be loaded in order, left to right. If the + pathname is nil, the system first checks if a module was defined + using defmodule and uses the pathnames so defined. If that fails, + it looks in the library directory for a file with name the same + as that of the module. Returns T if it loads the module." + (let ((module (canonicalize-module-name name))) + (unless (find module *modules* :test #'string=) + ;; Module is not already present. + (when (and pathname (not (listp pathname))) + ;; If there's a pathname or pathnames, ensure that it's a list. + (setf pathname (list pathname))) + (unless pathname + ;; If there's no pathname, try for a defmodule definition. + (setf pathname (module-files module))) + (unless pathname + ;; If there's still no pathname, try the library directory. + (when *library* + (setf pathname (concatenate 'string *library* module)) + ;; Test if the file exists. + ;; We assume that the lisp will default the file type + ;; appropriately. If it doesn't, use #+".fasl" or some + ;; such in the concatenate form above. + (if (probe-file pathname) + ;; If it exists, ensure we've got a list + (setf pathname (list pathname)) + ;; If the library file doesn't exist, we don't want + ;; a load error. + (setf pathname nil)))) + ;; Now that we've got the list of pathnames, let's load them. + (dolist (pname pathname T) + (load pname :verbose nil))))))) + +;;; ******************************** +;;; Set up Package ***************** +;;; ******************************** + + +;;; Unfortunately, lots of lisps have their own defsystems, some more +;;; primitive than others, all uncompatible, and all in the DEFSYSTEM +;;; package. To avoid name conflicts, we've decided to name this the +;;; MAKE package. A nice side-effect is that the short nickname +;;; MK is my initials. + +#-:cltl2 +(in-package "MAKE" :nicknames '("MK")) + +;;; For CLtL2 compatible lisps... +#+(and :excl :allegro-v4.0 :cltl2) +(defpackage "MAKE" (:nicknames "MK") (:use "COMMON-LISP") + (:import-from cltl1 *modules* provide require)) +#+:mcl +(defpackage "MAKE" (:nicknames "MK") (:use "COMMON-LISP") + (:import-from ccl *modules* provide require)) +#+(and :cltl2 (not (or (and :excl :allegro-v4.0) :mcl))) +(unless (find-package "MAKE") + (make-package "MAKE" :nicknames '("MK") :use '("COMMON-LISP"))) + +#+:cltl2 +(in-package "MAKE") + +#+(and :excl :allegro-v4.0 :cltl2) +(cltl1:provide 'make) +#+:mcl +(ccl:provide 'make) +#+(and :cltl2 (not (or (and :excl :allegro-v4.0) :mcl))) +(provide 'make) +#-:cltl2 +(provide 'make) + +(pushnew :mk-defsystem *features*) + +(eval-when (compile load eval) + (defvar *special-exports* + '(defsystem compile-system load-system)) + (defvar *exports* + '(operate-on-system oos afs-binary-directory afs-source-directory + files-in-system)) + + (defvar *other-exports* + '(*central-registry* *bin-subdir* + machine-type-translation software-type-translation + ;require + allegro-make-system-fasl + files-which-need-compilation + undefsystem + defined-systems + describe-system + *defsystem-version* + *compile-during-load* + *minimal-load* + *dont-redefine-require* + *files-missing-is-an-error* + *reload-systems-from-disk* + *source-pathname-default* + *binary-pathname-default* + ))) + +;;; The external interface consists of *exports* and *other-exports*. +(eval-when (compile load eval) + (export *exports*) + (export *special-exports*) + (export *other-exports*)) + +;;; We import these symbols into the USER package to make them +;;; easier to use. Since some lisps have already defined defsystem +;;; in the user package, we may have to shadowing-import it. +#-(OR :CMU :CCL :ALLEGRO :EXCL) +(eval-when (compile load eval) + (import *exports* #-:cltl2 "USER" #+:cltl2 "COMMON-LISP-USER") + (import *special-exports* #-:cltl2 "USER" #+:cltl2 "COMMON-LISP-USER")) +#+(OR :CMU :CCL :ALLEGRO :EXCL) +(eval-when (compile load eval) + (import *exports* #-:cltl2 "USER" #+:cltl2 "COMMON-LISP-USER") + (shadowing-import *special-exports* + #-:cltl2 "USER" + #+:cltl2 "COMMON-LISP-USER")) + +#-PCL(when (find-package "PCL") + (pushnew :pcl *modules*) + (pushnew :pcl *features*)) + +;;; ******************************** +;;; Defsystem Version ************** +;;; ******************************** +(defparameter *defsystem-version* "v2.5 08-JAN-92" + "Current version number/date for Defsystem.") + +;;; ******************************** +;;; Customizable System Parameters * +;;; ******************************** + +(defvar *dont-redefine-require* t ;nil + "If T, prevents the redefinition of REQUIRE. This is useful for + lisps that treat REQUIRE specially in the compiler.") + +;;; Change this variable to set up the location of a central +;;; repository for system definitions if you want one. +(defvar *central-registry* '() + "Central directory of system definitions. May be either a single + directory pathname, or a list of directory pathnames to be checked + after the local directory.") +(setq *central-registry* "../lisp/") + +(defvar *bin-subdir* ".bin/" + "The subdirectory of an AFS directory where the binaries are really kept.") + +;;; These variables set up defaults for operate-on-system, and are used +;;; for communication in lieu of parameter passing. Yes, this is bad, +;;; but it keeps the interface small. Also, in the case of the -if-no-binary +;;; variables, parameter passing would require multiple value returns +;;; from some functions. Why make life complicated? +(defvar *tell-user-when-done* nil + "If T, system will print ...DONE at the end of an operation") +(defvar *oos-verbose* nil + "Operate on System Verbose Mode") +(defvar *oos-test* nil + "Operate on System Test Mode") +(defvar *load-source-if-no-binary* nil + "If T, system will try loading the source if the binary is missing") +(defvar *bother-user-if-no-binary* t + "If T, the system will ask the user whether to load the source if + the binary is missing") +(defvar *load-source-instead-of-binary* nil + "If T, the system will load the source file instead of the binary.") +(defvar *compile-during-load* :query + "If T, the system will compile source files during load if the + binary file is missing. If :query, it will ask the user for + permission first.") +(defvar *minimal-load* nil + "If T, the system tries to avoid reloading files that were already loaded + and up to date.") + +(defvar *files-missing-is-an-error* t + "If both the source and binary files are missing, signal a continuable + error instead of just a warning.") + +(defvar *operations-propagate-to-subsystems* t + "If T, operations like :COMPILE and :LOAD propagate to subsystems + of a system that are defined either using a component-type of :system + or by another defsystem form.") + +;;; Particular to CMULisp +(defvar *compile-error-file-type* "err" + "File type of compilation error file in cmulisp") +(defvar *cmu-errors-to-terminal* t + "Argument to :errors-to-terminal in compile-file in cmulisp") +(defvar *cmu-errors-to-file* t + "If T, cmulisp will write an error file during compilation") + +;;; ******************************** +;;; Global Variables *************** +;;; ******************************** + +;;; Massage people's *features* into better shape. +(eval-when (compile load eval) + (dolist (feature *features*) + (when (and (symbolp feature) ; 3600 + (equal (symbol-name feature) "CMU")) + (pushnew :CMU *features*))) + + #+Lucid + (when (search "IBM RT PC" (machine-type)) + (pushnew :ibm-rt-pc *features*)) + ) + +;;; *filename-extensions* is a cons of the source and binary extensions. +(defvar *filename-extensions* + (car '(#+(and Symbolics Lispm) ("lisp" . "bin") + #+(and dec common vax (not ultrix)) ("LSP" . "FAS") + #+(and dec common vax ultrix) ("lsp" . "fas") + #+(or :kcl :ECL) ("lsp" . "o") + #+IBCL ("lsp" . "o") + #+Xerox ("lisp" . "dfasl") + ;; Lucid on Silicon Graphics + #+(and Lucid MIPS) ("lisp" . "mbin") + ;; the entry for (and lucid hp300) must precede + ;; that of (and lucid mc68000) for hp9000/300's running lucid, + ;; since *features* on hp9000/300's also include the :mc68000 + ;; feature. + #+(and lucid hp300) ("lisp" . "6bin") + #+(and Lucid MC68000) ("lisp" . "lbin") + #+(and Lucid Vax) ("lisp" . "vbin") + #+(and Lucid Prime) ("lisp" . "pbin") + #+(and Lucid SUNRise) ("lisp" . "sbin") + #+(and Lucid SPARC) ("lisp" . "sbin") + #+(and Lucid :IBM-RT-PC) ("lisp" . "bbin") + ;; PA is Precision Architecture, HP's 9000/800 RISC cpu + #+(and Lucid PA) ("lisp" . "hbin") + #+excl ("cl" . "fasl") + #+(and :CMU :SPARC) ("lisp" . "sparcf") + #+:CMU ("lisp" . "fasl") + #+PRIME ("lisp" . "pbin") + #+HP ("l" . "b") + #+TI ("lisp" . #.(string (si::local-binary-file-type))) + #+:gclisp ("LSP" . "F2S") + #+pyramid ("clisp" . "o") + #+:coral ("lisp" . "fasl") + ;; Harlequin LispWorks on Mips M2000 + #+(and :mips :lispworks) ("lisp" . "mfasl") + + ;; Otherwise, + ("lisp" . "lbin"))) + "Filename extensions for Common Lisp. A cons of the form + (Source-Extension . Binary-Extension). If the system is + unknown (as in *features* not known), defaults to lisp and lbin.") + +;;; There is no real support for this variable being nil, so don't change it. +;;; Note that in any event, the toplevel system (defined with defsystem) +;;; will have its dependencies delayed. Not having dependencies delayed +;;; might be useful if we define several systems within one defsystem. +(defvar *system-dependencies-delayed* t + "If T, system dependencies are expanded at run time") + +;;; Replace this with consp, dammit! +(defun non-empty-listp (list) + (and list (listp list))) + +;;; ******************************** +;;; Component Operation Definition * +;;; ******************************** +(defvar *component-operations* (make-hash-table :test #'equal) + "Hash table of (operation-name function) pairs.") +(defun component-operation (name &optional operation) + (if operation + (setf (gethash name *component-operations*) operation) + (gethash name *component-operations*))) + +;;; ******************************** +;;; AFS @sys immitator ************* +;;; ******************************** + +;;; mc 11-Apr-91: Bashes MCL's point reader, so commented out. +#-:mcl +(eval-when (compile load eval) + ;; Define #@"foo" as a shorthand for (afs-binary-directory "foo"). + ;; For example, + ;; #@"foo" + ;; "foo/.bin/rt_mach/" + (set-dispatch-macro-character + #\# #\@ + #'(lambda (stream char arg) + (declare (ignore char arg)) + `(afs-binary-directory ',(read stream t nil t))))) + +(defun afs-binary-directory (root-directory) + ;; Function for obtaining the directory AFS's @sys feature would have + ;; chosen when we're not in AFS. This function is useful as the argument + ;; to :binary-pathname in defsystem. For example, + ;; :binary-pathname (afs-binary-directory "scanner/") + (let ((machine (machine-type-translation (machine-type))) + (software (software-type-translation (software-type)))) + ;; pmax_mach rt_mach sun3_35 sun3_mach vax_mach + (setq root-directory (namestring root-directory)) + (setq root-directory (ensure-trailing-slash root-directory)) + (format nil "~A~@[~A~]~@[~A/~]" + root-directory + *bin-subdir* + (afs-component machine software)))) + +(defun afs-source-directory (root-directory &optional version-flag) + ;; Function for obtaining the directory AFS's @sys feature would have + ;; chosen when we're not in AFS. This function is useful as the argument + ;; to :source-pathname in defsystem. + (setq root-directory (namestring root-directory)) + (setq root-directory (ensure-trailing-slash root-directory)) + (format nil "~A~@[~A/~]" + root-directory + (and version-flag (translate-version *version*)))) + +(defun null-string (s) + (when (stringp s) + (string-equal s ""))) + +(defun ensure-trailing-slash (dir) + (if (and dir + (not (null-string dir)) + (not (char= (char dir + (1- (length dir))) + #\/))) + (concatenate 'string dir "/") + dir)) + +(defun afs-component (machine software) + (format nil "~@[~A~]~@[_~A~]" + machine + (or software "mach"))) + +(defvar *machine-type-alist* (make-hash-table :test #'equal) + "Hash table for retrieving the machine-type") +(defun machine-type-translation (name &optional operation) + (if operation + (setf (gethash (string-upcase name) *machine-type-alist*) operation) + (gethash (string-upcase name) *machine-type-alist*))) + +(machine-type-translation "IBM RT PC" "rt") +(machine-type-translation "DEC 3100" "pmax") +(machine-type-translation "DEC VAX-11" "vax") +(machine-type-translation "Sun3" "sun3") +(machine-type-translation "Sun-4" "sun4") +#+(and :lucid :sun :mc68000) +(machine-type-translation "unknown" "sun3") + + +(defvar *software-type-alist* (make-hash-table :test #'equal) + "Hash table for retrieving the software-type") +(defun software-type-translation (name &optional operation) + (if operation + (setf (gethash (string-upcase name) *software-type-alist*) operation) + (gethash (string-upcase name) *software-type-alist*))) + +(software-type-translation "BSD UNIX" "mach") ; "unix" +(software-type-translation "Ultrix" "mach") ; "ultrix" +(software-type-translation "SunOS" "SunOS") +(software-type-translation "MACH/4.3BSD" "mach") +#+:lucid +(software-type-translation "Unix" + #+:lcl4.0 "4.0" + #+(and :lcl3.0 (not :lcl4.0)) "3.0") + +;;; ******************************** +;;; System Names ******************* +;;; ******************************** +(defun canonicalize-system-name (name) + ;; Originally we were storing systems using GET. This meant that the + ;; name of a system had to be a symbol, so we interned the symbols + ;; in the keyword package to avoid package dependencies. Now that we're + ;; storing the systems in a hash table, we've switched to using strings. + ;; Since the hash table is case sensitive, we use uppercase strings. + ;; (Names of modules and files may be symbols or strings.) + #|(if (keywordp name) + name + (intern (string-upcase (string name)) "KEYWORD"))|# + (if (stringp name) name (string-upcase (string name)))) + +(defvar *defined-systems* (make-hash-table :test #'equal) + "Hash table containing the definitions of all known systems.") + +(defun get-system (name) + "Returns the definition of the system named NAME." + (gethash (canonicalize-system-name name) *defined-systems*)) + +(defsetf get-system (name) (value) + `(setf (gethash (canonicalize-system-name ,name) *defined-systems*) ,value)) + +(defun undefsystem (name) + "Removes the definition of the system named NAME." + (setf (get-system name) nil)) + +(defun defined-systems () + "Returns a list of defined systems." + (let ((result nil)) + (maphash #'(lambda (key value) + (declare (ignore key)) + (push value result)) + *defined-systems*) + result)) + +;;; ******************************** +;;; Directory Pathname Hacking ***** +;;; ******************************** + +;;; Unix example: An absolute directory starts with / while a +;;; relative directory doesn't. A directory ends with /, while +;;; a file's pathname doesn't. This is important 'cause +;;; (pathname-directory "foo/bar") will return "foo" and not "foo/". + +;;; I haven't been able to test the fix to the problem with symbolics +;;; hosts. Essentially, append-directories seems to have been tacking +;;; the default host onto the front of the pathname (e.g., mk::source-pathname +;;; gets a "B:" on front) and this overrides the :host specified in the +;;; component. The value of :host should override that specified in +;;; the :source-pathname and the default file server. If this doesn't +;;; fix things, specifying the host in the root pathname "F:>root-dir>" +;;; may be a good workaround. + +;;; Need to verify that merging of pathnames where modules are located +;;; on different devices (in VMS-based VAXLisp) now works. + +;;; Merge-pathnames works for VMS systems. In VMS systems, the directory +;;; part is enclosed in square brackets, e.g., +;;; "[root.child.child_child]" or "[root.][child.][child_child]" +;;; To concatenate directories merge-pathnames works as follows: +;;; (merge-pathnames "" "[root]") ==> "[root]" +;;; (merge-pathnames "[root.]" "[son]file.ext") ==> "[root.son]file.ext" +;;; (merge-pathnames "[root.]file.ext" "[son]") ==> "[root.son]file.ext" +;;; (merge-pathnames "[root]file.ext" "[son]") ==> "[root]file.ext" +;;; Thus the problem with the #-VMS code was that it was merging x y into +;;; [[x]][y] instead of [x][y] or [x]y. + +;;; Miscellaneous notes: +;;; On GCLisp, the following are equivalent: +;;; "\\root\\subdir\\BAZ" +;;; "/root/subdir/BAZ" +;;; On VAXLisp, the following are equivalent: +;;; "[root.subdir]BAZ" +;;; "[root.][subdir]BAZ" +;;; Use #+:vaxlisp for VAXLisp 3.0, #+(and vms dec common vax) for v2.2 + +(defun new-append-directories (absolute-dir relative-dir) + ;; Version of append-directories for CLtL2-compliant lisps. In particular, + ;; they must conform to section 23.1.3 "Structured Directories". We are + ;; willing to fix minor aberations in this function, but not major ones. + ;; Tested in Allegro CL 4.0 [SPARC], Allegro CL 3.1.12 [DEC 3100], + ;; CMU CL old and new compilers, Lucid 3.0, Lucid 4.0. + (setf absolute-dir (or absolute-dir "") + relative-dir (or relative-dir "")) + (let* ((abs-dir (pathname absolute-dir)) + (rel-dir (pathname relative-dir)) + (host (pathname-host abs-dir)) + (device (if (null-string absolute-dir) ; fix for CMU CL old compiler + (pathname-device rel-dir) + (pathname-device abs-dir))) + (abs-directory (coerce (pathname-directory abs-dir) 'list)) + (abs-keyword (when (keywordp (car abs-directory)) + (pop abs-directory))) + (abs-name (file-namestring abs-dir)) ; was pathname-name + (rel-directory (coerce (pathname-directory rel-dir) 'list)) + (rel-keyword (when (keywordp (car rel-directory)) + (pop rel-directory))) + (rel-file (file-namestring rel-dir)) + (directory nil)) + ;; Allegro v4.0 parses "/foo" into :directory '(:absolute :root) + ;; and filename "foo". The namestring of a pathname with + ;; directory '(:absolute :root "foo") ignores everything after the + ;; :root. + #+:allegro-v4.0(when (eq (car abs-directory) :root) (pop abs-directory)) + #+:allegro-v4.0(when (eq (car rel-directory) :root) (pop rel-directory)) + (when (and abs-name (not (null-string abs-name))) ; was abs-name + (cond ((and (null abs-directory) (null abs-keyword)) + #-(or :lucid :kcl :ECL) (setf abs-keyword :relative) + (setf abs-directory (list abs-name))) + (t + (setf abs-directory (append abs-directory (list abs-name)))))) + (when (and (null abs-directory) + (or (null abs-keyword) + ;; In Lucid, an abs-dir of nil gets a keyword of + ;; :relative since (pathname-directory (pathname "")) + ;; returns (:relative) instead of nil. + #+:lucid (eq abs-keyword :relative)) + rel-keyword) + (setf abs-keyword rel-keyword)) + (setf directory (append abs-directory rel-directory)) + (when abs-keyword (setf directory (cons abs-keyword directory))) + (namestring + (make-pathname :host host + :device device + :directory #-:cmu directory + #+:cmu (if (find-package :common-lisp) +;; no longer required in CMUcl 16e -- stolcke 9/17/92 + directory + (coerce directory 'simple-vector)) + :directory directory + :name rel-file)))) + +(defparameter *append-dirs-tests* + '("~/foo/" "baz/bar.lisp" + "~/foo" "baz/bar.lisp" + "/foo/bar/" "baz/barf.lisp" + "/foo/bar/" "/baz/barf.lisp" + "foo/bar/" "baz/barf.lisp" + "foo/bar" "baz/barf.lisp" + "foo/bar" "/baz/barf.lisp" + "foo/bar/" "/baz/barf.lisp" + "/foo/bar/" nil + "foo/bar/" nil + "foo/bar" nil + "foo" "bar" + nil "baz/barf.lisp" + nil "/baz/barf.lisp" + nil nil)) + +(defun test-new-append-directories (&optional (test-dirs *append-dirs-tests*)) + (do* ((dir-list test-dirs (cddr dir-list)) + (abs-dir (car dir-list) (car dir-list)) + (rel-dir (cadr dir-list) (cadr dir-list))) + ((null dir-list) (values)) + (format t "~&ABS: ~S ~18TREL: ~S ~41TResult: ~S" + abs-dir rel-dir (new-append-directories abs-dir rel-dir)))) + +#| + (test-new-append-directories) + +ABS: "~/foo/" REL: "baz/bar.lisp" Result: "/usr0/mkant/foo/baz/bar.lisp" +ABS: "~/foo" REL: "baz/bar.lisp" Result: "/usr0/mkant/foo/baz/bar.lisp" +ABS: "/foo/bar/" REL: "baz/barf.lisp" Result: "/foo/bar/baz/barf.lisp" +ABS: "/foo/bar/" REL: "/baz/barf.lisp" Result: "/foo/bar/baz/barf.lisp" +ABS: "foo/bar/" REL: "baz/barf.lisp" Result: "foo/bar/baz/barf.lisp" +ABS: "foo/bar" REL: "baz/barf.lisp" Result: "foo/bar/baz/barf.lisp" +ABS: "foo/bar" REL: "/baz/barf.lisp" Result: "foo/bar/baz/barf.lisp" +ABS: "foo/bar/" REL: "/baz/barf.lisp" Result: "foo/bar/baz/barf.lisp" +ABS: "/foo/bar/" REL: NIL Result: "/foo/bar/" +ABS: "foo/bar/" REL: NIL Result: "foo/bar/" +ABS: "foo/bar" REL: NIL Result: "foo/bar/" +ABS: NIL REL: "baz/barf.lisp" Result: "baz/barf.lisp" +ABS: NIL REL: "/baz/barf.lisp" Result: "/baz/barf.lisp" +ABS: NIL REL: NIL Result: "" + +|# + +(defun append-directories (absolute-directory relative-directory) + "There is no CL primitive for tacking a subdirectory onto a directory. + We need such a function because defsystem has both absolute and + relative pathnames in the modules. This is a somewhat ugly hack which + seems to work most of the time. We assume that ABSOLUTE-DIRECTORY + is a directory, with no filename stuck on the end. Relative-directory, + however, may have a filename stuck on the end." + (when (or absolute-directory relative-directory) + (cond + #+:logical-pathnames-mk + ((eq (lp:pathname-host-type absolute-directory) :logical) + ;; For use with logical pathnames package. + (lp:append-logical-directories absolute-directory relative-directory)) + (t + ;; In VMS, merge-pathnames actually does what we want!!! + #+:VMS(namestring (merge-pathnames (or absolute-directory "") + (or relative-directory ""))) + #+:macl1.3.2(namestring (make-pathname :directory absolute-directory + :name relative-directory)) + ;; Cross your fingers and pray. + #-(or :VMS :macl1.3.2) + (new-append-directories absolute-directory relative-directory))))) + +#| +(defun append-directories (absolute-directory relative-directory) + "There is no CL primitive for tacking a subdirectory onto a directory. + We need such a function because defsystem has both absolute and + relative pathnames in the modules. This is a very gross hack which + seems to work most of the time. We assume that ABSOLUTE-DIRECTORY + is a directory, with no filename stuck on the end. Relative-directory, + however, may have a filename stuck on the end. We assume that + if we do a (make-pathname :directory abs-directory :name rel-directory) + it will do what we want. The #+ and #-'s that appear before this + form are used to massage abs-directory and rel-directory into a + format acceptable to make-pathname in the particular lisp." + (when (or absolute-directory relative-directory) + (cond + #+:logical-pathnames-mk + ((eq (pathname-host-type absolute-directory) :logical) + ;; For use with logical pathnames package. + (lp::append-logical-directories absolute-directory relative-directory)) + (t + ;; Allegro CL barfs if abs-dir is "", so we replace it with NIL. + #+:ExCL(when (and (stringp absolute-directory) + (null-string absolute-directory)) + (setq absolute-directory nil)) + ;; CMU CL needs a / at the end of absolute directory, so we + ;; coerce abs-dir to a namestring and then check the last character + ;; of the namestring. An alternate method of doing this might + ;; be to break the directory into components, cons :absolute or + ;; :relative on the front, and hand that off to make-pathname. + #+:CMU(when (pathnamep absolute-directory) + (setq absolute-directory (namestring absolute-directory))) + #+:CMU(when (and absolute-directory + (not (null-string absolute-directory)) + (not (char= (char absolute-directory + (1- (length absolute-directory))) + #\/))) + (setq absolute-directory + (concatenate 'string absolute-directory "/"))) + #+:CMU(when (pathnamep relative-directory) + (setq relative-directory (namestring relative-directory))) + ;; In VMS, merge-pathnames actually does what we want!!! + #+:VMS(namestring (merge-pathnames (or absolute-directory "") + (or relative-directory ""))) + ;; For Sun Common Lisp 4.0, which is the same as Lucid 4.0. + ;; For this one, we need to break the string up into components, + ;; and tack a :ROOT on the front. + ;; The :lucid probably should be removed below for it to work properly + ;; in Lucid 3.0. + #+(or (and (not :excl) :SUN) :lcl4.0 :lucid) + (namestring (make-pathname + :directory (cons :ROOT + (parse-slashed-pathname + (merge-pathnames absolute-directory))) + :name relative-directory)) + #|(namestring (make-pathname + :directory (list :ROOT (or absolute-directory "")) + :name relative-directory))|# + ;; Cross your fingers and pray. + #-(or :VMS (and (not :excl) :SUN) :lcl4.0 :lucid) + (namestring (make-pathname :directory absolute-directory + #+:cmu :device #+:cmu :absolute + #+:symbolics :host #+:symbolics nil + :name relative-directory)))))) + +(defun parse-with-delimiter (line &optional (delim #\/)) + (let ((pos (position delim line))) + (cond (pos + (cons (subseq line 0 pos) + (parse-with-delimiter (subseq line (1+ pos)) delim))) + (t + (list line))))) + +(defun parse-slashed-pathname (directory) + "Parses strings like \"/usr/mkant/Public/\" into a list of + the directory components: '(\"usr\" \"mkant\" \"Public\"), + with null components (\"\") removed." + (if directory + (remove-if #'(lambda (string) (string-equal string "")) + (parse-with-delimiter directory #\/)) + (list ""))) +|# + +#| +;;; This was a try at appending a subdirectory onto a directory. +;;; It failed. We're keeping this around to prevent future mistakes +;;; of a similar sort. +(defun merge-directories (absolute-directory relative-directory) + ;; replace concatenate with something more intelligent + ;; i.e., concatenation won't work with some directories. + ;; it should also behave well if the parent directory + ;; has a filename at the end, or if the relative-directory ain't relative + (when absolute-directory + (setq absolute-directory (pathname-directory absolute-directory))) + (concatenate 'string + (or absolute-directory "") + (or relative-directory ""))) +|# + + + +#| + (defun d (d n) (namestring (make-pathname :directory d :name n))) + +D + (d "~/foo/" "baz/bar.lisp") +"/usr0/mkant/foo/baz/bar.lisp" + + (d "~/foo" "baz/bar.lisp") +"/usr0/mkant/foo/baz/bar.lisp" + + (d "/foo/bar/" "baz/barf.lisp") +"/foo/bar/baz/barf.lisp" + + (d "foo/bar/" "baz/barf.lisp") +"foo/bar/baz/barf.lisp" + + (d "foo/bar" "baz/barf.lisp") +"foo/bar/baz/barf.lisp" + + (d "foo/bar" "/baz/barf.lisp") +"foo/bar//baz/barf.lisp" + + (d "foo/bar" nil) +"foo/bar/" + + (d nil "baz/barf.lisp") +"baz/barf.lisp" + + (d nil nil) +"" + +|# + + +(defun namestring-or-nil (pathname) + (when pathname + (namestring pathname))) + +(defun new-file-type (pathname type) + (make-pathname + :host (pathname-host pathname) + :device (pathname-device pathname) + :directory (pathname-directory pathname) + :name (pathname-name pathname) + :type type + :version (pathname-version pathname))) + + + +;;; ******************************** +;;; Component Defstruct ************ +;;; ******************************** +(defvar *source-pathname-default* nil + "Default value of :source-pathname keyword in DEFSYSTEM. Set this to + \"\" to avoid having to type :source-pathname \"\" all the time.") +(defvar *binary-pathname-default* nil + "Default value of :binary-pathname keyword in DEFSYSTEM.") + +(defstruct (topological-sort-node (:conc-name topsort-)) + color + time) + +(defstruct (component (:include topological-sort-node) + (:print-function print-component)) + type ; :defsystem, :system, :subsystem, :module, :file, or :private-file + name ; a symbol or string + indent ; number of characters of indent in verbose output to the user. + host ; the pathname host (i.e., "/../a") + device ; the pathname device + source-root-dir + ;; relative or absolute (starts with "/"), directory or file (ends with "/") + (source-pathname *source-pathname-default*) + source-extension ; a string, e.g., "lisp". If nil, uses default for machine-type + (binary-pathname *binary-pathname-default*) + binary-root-dir + binary-extension ; a string, e.g., "fasl". If nil, uses default for machine-type + package ; package for use-package + components ; a list of components comprising this component's definition + depends-on ; a list of the components this one depends on. may refer only + ; to the components at the same level as this one. + initially-do ; form to evaluate before the operation + finally-do ; form to evaluate after the operation + compile-form ; for foreign libraries + load-form ; for foreign libraries +; load-time ; The file-write-date of the binary/source file loaded. + ;; If load-only is T, will not compile the file on operation :compile. + ;; In other words, for files which are :load-only T, loading the file + ;; satisfies any demand to recompile. + load-only ; If T, will not compile this file on operation :compile. + ;; If compile-only is T, will not load the file on operation :compile. + ;; Either compiles or loads the file, but not both. In other words, + ;; compiling the file satisfies the demand to load it. This is useful + ;; for PCL defmethod and defclass definitions, which wrap a + ;; (eval-when (compile load eval) ...) around the body of the definition. + ;; This saves time in some lisps. + compile-only ; If T, will not load this file on operation :compile. +) + +(defvar *file-load-time-table* (make-hash-table :test #'equal) + "Hash table of file-write-dates for the system definitions and + files in the system definitions.") +(defun component-load-time (component) + (when component + (etypecase component + (string (gethash component *file-load-time-table*)) + (pathname (gethash (namestring component) *file-load-time-table*)) + (component + (ecase (component-type component) + (:defsystem + (let ((name (component-name component)) + (path nil)) + (when (and name + (setf path (compute-system-path name nil))) + (gethash (namestring path) *file-load-time-table*)))) + ((:file :private-file) + ;; Use only :source pathname to identify component's + ;; load time. + (let ((path (component-full-pathname component :source))) + (when path + (gethash (namestring path) *file-load-time-table*))))))))) +(defsetf component-load-time (component) (value) + `(when ,component + (etypecase ,component + (string (setf (gethash ,component *file-load-time-table*) ,value)) + (pathname (setf (gethash (namestring ,component) *file-load-time-table*) + ,value)) + (component + (ecase (component-type ,component) + (:defsystem + (let ((name (component-name ,component)) + (path nil)) + (when (and name + (setf path (compute-system-path name nil))) + (setf (gethash (namestring path) *file-load-time-table*) + ,value)))) + ((:file :private-file) + ;; Use only :source pathname to identify file. + (let ((path (component-full-pathname ,component :source))) + (when path + (setf (gethash (namestring path) *file-load-time-table*) + ,value))))))))) + +(defun compute-system-path (module-name definition-pname) + (let* ((filename (format nil "~A.system" + (if (symbolp module-name) + (string-downcase (string module-name)) + module-name)))) + (or (when definition-pname ; given pathname for system def + (probe-file definition-pname)) + (probe-file filename) ; try current dir + (when *central-registry* ; central registry + (if (listp *central-registry*) + (dolist (registry *central-registry*) + (let ((file (probe-file (append-directories registry + filename)))) + (when file (return file)))) + (probe-file (append-directories *central-registry* filename)))) + ))) + +(defvar *reload-systems-from-disk* t + "If T, always tries to reload newer system definitions from disk. + Otherwise first tries to find the system definition in the current + environment.") + +(defun FIND-SYSTEM (system-name &optional (mode :ask) definition-pname) + "Returns the system named SYSTEM-NAME. If not already loaded, loads it. + This allows operate-on-system to work on non-loaded as well as + loaded system definitions. DEFINITION-PNAME is the pathname for + the system definition, if provided." + (ecase mode + (:ASK + (or (get-system system-name) + (when (y-or-n-p-wait + #\y 20 + "System ~A not loaded. Shall I try loading it? " + system-name) + (find-system system-name :load definition-pname)))) + (:ERROR + (or (get-system system-name) + (error "Can't find system named ~s." system-name))) + (:LOAD-OR-NIL + (let ((system (get-system system-name))) + (or (unless *reload-systems-from-disk* system) + (let ((path (compute-system-path system-name definition-pname))) + (when (and path + (or (null system) + (null (component-load-time path)) + (< (component-load-time path) + (file-write-date path)))) + (load path) + (setf system (get-system system-name)) + (when system + (setf (component-load-time path) + (file-write-date path)))) + system) + system))) + (:LOAD + (or (unless *reload-systems-from-disk* (get-system system-name)) + (or (find-system system-name :load-or-nil definition-pname) + (error "Can't find system named ~s." system-name)))))) + +(defun print-component (component stream depth) + (declare (ignore depth)) + (format stream "#<~:@(~A~): ~A>" + (component-type component) + (component-name component))) + +(defun describe-system (name &optional (stream *standard-output*)) + "Prints a description of the system to the stream. If NAME is the + name of a system, gets it and prints a description of the system. + If NAME is a component, prints a description of the component." + (let ((system (if (typep name 'component) name (find-system name :load)))) + (format stream "~&~A ~A: ~ + ~@[~& Host: ~A~]~ + ~@[~& Device: ~A~]~ + ~@[~& Package: ~A~]~ + ~& Source: ~@[~A~] ~@[~A~] ~@[~A~]~ + ~& Binary: ~@[~A~] ~@[~A~] ~@[~A~]~ + ~@[~& Depends On: ~A ~]~& Components: ~{~15T~A~&~}" + (component-type system) + (component-name system) + (component-host system) + (component-device system) + (component-package system) + (component-root-dir system :source) + (component-pathname system :source) + (component-extension system :source) + (component-root-dir system :binary) + (component-pathname system :binary) + (component-extension system :binary) + (component-depends-on system) + (component-components system)) + #|(when recursive + (dolist (component (component-components system)) + (describe-system component stream recursive)))|# + system)) + +(defun canonicalize-component-name (component) + ;; Within the component, the name is a string. + (if (typep (component-name component) 'string) + ;; Unnecessary to change it, so just return it, same case + (component-name component) + ;; Otherwise, make it a downcase string + (setf (component-name component) + (string-downcase (string (component-name component)))))) + +(defun component-pathname (component type) + (when component + (case type + (:source (component-source-pathname component)) + (:binary (component-binary-pathname component)) + (:error (component-error-pathname component))))) +(defun component-error-pathname (component) + (let ((binary (component-pathname component :binary))) + (new-file-type binary *compile-error-file-type*))) +(defsetf component-pathname (component type) (value) + `(when ,component + (case ,type + (:source (setf (component-source-pathname ,component) ,value)) + (:binary (setf (component-binary-pathname ,component) ,value))))) + +(defun component-root-dir (component type) + (when component + (case type + (:source (component-source-root-dir component)) + ((:binary :error) (component-binary-root-dir component)) + ))) +(defsetf component-root-dir (component type) (value) + `(when ,component + (case ,type + (:source (setf (component-source-root-dir ,component) ,value)) + (:binary (setf (component-binary-root-dir ,component) ,value))))) + +(defvar *version-dir* nil + "The version subdir. bound in oos.") +(defvar *version-replace* nil + "The version replace. bound in oos.") +(defvar *version* nil + "Default version") +(defun component-full-pathname (component type &optional (version *version*) + &aux version-dir replace) + (when component + ;; If the pathname-type is :binary and the root pathname is null, + ;; distribute the binaries among the sources (= use :source pathname). + ;; This assumes that the component's :source pathname has been set + ;; before the :binary one. + (if version + (multiple-value-setq (version-dir replace) (translate-version version)) + (setq version-dir *version-dir* replace *version-replace*)) + (let ((pathname + (append-directories + (if replace + version-dir + (append-directories (component-root-dir component type) + version-dir)) + (component-pathname component type)))) + ;; When a logical pathname is used, it must first be translated to + ;; a physical pathname. This isn't strictly correct. What should happen + ;; is we fill in the appropriate slots of the logical pathname, and + ;; then return the logical pathname for use by compile-file & friends. + ;; But calling translate-logical-pathname to return the actual pathname + ;; should do for now. + #+:logical-pathnames-mk + (when (eq (lp:pathname-host-type pathname) :logical) + ;;(setf (lp::%logical-pathname-type pathname) + ;; (component-extension component type)) + (setf pathname (lp:translate-logical-pathname pathname))) + + (make-pathname :name (pathname-name pathname) + :type (component-extension component type) +;; couldn't get this to work under CMUcl 16e -- stolcke 9/17/92 + #-:cmu :host #-:cmu (when (component-host component) + ;; MCL2.0b1 causes an error on + ;; (pathname-host nil) + (pathname-host (component-host component))) +;; in CMUcl 15d not needed -- stolcke 9/17/92 + ;; :device #+CMU :absolute + ;; #-CMU (pathname-device (component-device component)) +;; but CMUcl 16e doesn't tolerate (pathname-device nil) + :device (when (component-device component) + (pathname-device (component-device component))) + ;; :version :newest + ;; Use :directory instead of :defaults + :directory (pathname-directory pathname))))) + +(defun translate-version (version) + ;; Value returns the version directory and whether it replaces + ;; the entire root (t) or is a subdirectory. + ;; Version may be nil to signify no subdirectory, + ;; a symbol, such as alpha, beta, omega, :alpha, mark, which + ;; specifies a subdirectory of the root, or + ;; a string, which replaces the root. + (cond ((null version) + (values "" nil)) + ((symbolp version) + (values (let ((sversion (string version))) + (if (find-if #'lower-case-p sversion) + sversion + (string-downcase sversion))) + nil)) + ((stringp version) + (values version t)) + (t (error "~&; Illegal version ~S" version)))) + +(defun component-extension (component type) + (case type + (:source (component-source-extension component)) + (:binary (component-binary-extension component)) + (:error *compile-error-file-type*))) +(defsetf component-extension (component type) (value) + `(case ,type + (:source (setf (component-source-extension ,component) ,value)) + (:binary (setf (component-binary-extension ,component) ,value)) + (:error (setf *compile-error-file-type* ,value)))) + +;;; ******************************** +;;; System Definition ************** +;;; ******************************** +(defmacro defsystem (name &rest definition-body) + `(create-component :defsystem ',name ',definition-body nil 0)) + +(defun create-component (type name definition-body &optional parent (indent 0)) + (let ((component (apply #'make-component :type type :name name :indent indent definition-body))) + ;; Set up :load-only attribute + (unless (find :load-only definition-body) + ;; If the :load-only attribute wasn't specified, + ;; inherit it from the parent. If no parent, default it to nil. + (setf (component-load-only component) + (when parent + (component-load-only parent)))) + ;; Set up :compile-only attribute + (unless (find :compile-only definition-body) + ;; If the :compile-only attribute wasn't specified, + ;; inherit it from the parent. If no parent, default it to nil. + (setf (component-compile-only component) + (when parent + (component-compile-only parent)))) + + ;; Initializations/after makes + (canonicalize-component-name component) + + ;; Inherit package from parent if not specified. + (setf (component-package component) + (or (component-package component) + (when parent (component-package parent)))) + + ;; Type specific setup: + (when (or (eq type :defsystem) (eq type :system) (eq type :subsystem)) + (setf (get-system name) component)) + + ;; Set up the component's pathname + (create-component-pathnames component parent) + + ;; If there are any components of the component, expand them too. + (expand-component-components component (+ indent 2)) + + ;; Make depends-on refer to structs instead of names. + (link-component-depends-on (component-components component)) + + ;; Design Decision: Topologically sort the dependency graph at + ;; time of definition instead of at time of use. Probably saves a + ;; little bit of time for the user. + + ;; Topological Sort the components at this level. + (setf (component-components component) + (topological-sort (component-components component))) + + ;; Return the component. + component)) + +(defun create-component-pathnames (component parent) + ;; Evaluate the root dir arg + (setf (component-root-dir component :source) + (eval (component-root-dir component :source))) + (setf (component-root-dir component :binary) + (eval (component-root-dir component :binary))) + ;; Evaluate the pathname arg + (setf (component-pathname component :source) + (eval (component-pathname component :source))) + (setf (component-pathname component :binary) + (eval (component-pathname component :binary))) + ;; Pass along the host and devices + (setf (component-host component) + (or (component-host component) + (when parent (component-host parent)))) + (setf (component-device component) + (or (component-device component) + (when parent (component-device parent)))) + ;; Set up extension defaults + (setf (component-extension component :source) + (or (component-extension component :source) ; for local defaulting + (when parent ; parent's default + (component-extension parent :source)) + (car *filename-extensions*))) ; system default + (setf (component-extension component :binary) + (or (component-extension component :binary) ; for local defaulting + (when parent ; parent's default + (component-extension parent :binary)) + (cdr *filename-extensions*))) ; system default + ;; Set up pathname defaults -- expand with parent + ;; We must set up the source pathname before the binary pathname + ;; to allow distribution of binaries among the sources to work. + (generate-component-pathname component parent :source) + (generate-component-pathname component parent :binary)) + +;; maybe file's inheriting of pathnames should be moved elsewhere? +(defun generate-component-pathname (component parent pathname-type) + ;; Pieces together a pathname for the component based on its component-type. + ;; Assumes source defined first. + ;; Null binary pathnames inherit from source instead of the component's + ;; name. This allows binaries to be distributed among the source if + ;; binary pathnames are not specified. Or if the root directory is + ;; specified for binaries, but no module directories, it inherits + ;; parallel directory structure. + (case (component-type component) + ((:defsystem :system) ; Absolute Pathname + ;; Set the root-dir to be the absolute pathname + (setf (component-root-dir component pathname-type) + (or (component-pathname component pathname-type) + (when (eq pathname-type :binary) + ;; When the binary root is nil, use source. + (component-root-dir component :source))) ) + ;; Set the relative pathname to be nil + (setf (component-pathname component pathname-type) + nil));; should this be "" instead? + ;; If the name of the component-pathname is nil, it + ;; defaults to the name of the component. Use "" to + ;; avoid this defaulting. + (:private-file ; Absolute Pathname + ;; Root-dir is the directory part of the pathname + (setf (component-root-dir component pathname-type) + "" + #+ignore(or (when (component-pathname component pathname-type) + (pathname-directory + (component-pathname component pathname-type))) + (when (eq pathname-type :binary) + ;; When the binary root is nil, use source. + (component-root-dir component :source))) + ) + ;; The relative pathname is the name part + (setf (component-pathname component pathname-type) + (or (when (and (eq pathname-type :binary) + (null (component-pathname component :binary))) + ;; When the binary-pathname is nil use source. + (component-pathname component :source)) + (or (when (component-pathname component pathname-type) +; (pathname-name ) + (component-pathname component pathname-type)) + (component-name component))))) + ((:module :subsystem) ; Pathname relative to parent. + ;; Inherit root-dir from parent + (setf (component-root-dir component pathname-type) + (component-root-dir parent pathname-type)) + ;; Tack the relative-dir onto the pathname + (setf (component-pathname component pathname-type) + (or (when (and (eq pathname-type :binary) + (null (component-pathname component :binary))) + ;; When the binary-pathname is nil use source. + (component-pathname component :source)) + (append-directories + (component-pathname parent pathname-type) + (or (component-pathname component pathname-type) + (component-name component)))))) + (:file ; Pathname relative to parent. + ;; Inherit root-dir from parent + (setf (component-root-dir component pathname-type) + (component-root-dir parent pathname-type)) + ;; Tack the relative-dir onto the pathname + (setf (component-pathname component pathname-type) + (or (append-directories + (component-pathname parent pathname-type) + (or (component-pathname component pathname-type) + (component-name component) + (when (eq pathname-type :binary) + ;; When the binary-pathname is nil use source. + (component-pathname component :source))))))) + )) + +(defun expand-component-components (component &optional (indent 0)) + (setf (component-components component) + (remove-if #'null + (mapcar #'(lambda (definition) + (expand-component-definition definition + component indent)) + (component-components component))))) + +(defun expand-component-definition (definition parent &optional (indent 0)) + ;; Should do some checking for malformed definitions here. + (cond ((null definition) nil) + ((stringp definition) + ;; Strings are assumed to be of type :file + (create-component :file definition nil parent indent)) + ((and (listp definition) + (not (member (car definition) + '(:defsystem :system :subsystem + :module :file :private-file)))) + ;; Lists whose first element is not a component type + ;; are assumed to be of type :file + (create-component :file (car definition) (cdr definition) parent indent)) + ((listp definition) + ;; Otherwise, it is (we hope) a normal form definition + (create-component (car definition) ; type + (cadr definition) ; name + (cddr definition) ; definition body + parent ; parent + indent) ; indent + ))) + +(defun link-component-depends-on (components) + (dolist (component components) + (unless (and *system-dependencies-delayed* + (eq (component-type component) :defsystem)) + (setf (component-depends-on component) + (mapcar #'(lambda (dependency) + (let ((parent (find (string dependency) components + :key #'component-name + :test #'string-equal))) + (cond (parent parent) + ;; make it more intelligent about the following + (t (warn "Dependency ~S of component ~S not found." + dependency component))))) + + (component-depends-on component)))))) + +;;; ******************************** +;;; Topological Sort the Graph ***** +;;; ******************************** +(defun topological-sort (list &aux (time 0)) + ;; The algorithm works by calling depth-first-search to compute the + ;; blackening times for each vertex, and then sorts the vertices into + ;; reverse order by blackening time. + (labels ((dfs-visit (node) + (setf (topsort-color node) 'gray) + (unless (and *system-dependencies-delayed* + (eq (component-type node) :defsystem)) + (dolist (child (component-depends-on node)) + (cond ((eq (topsort-color child) 'white) + (dfs-visit child)) + ((eq (topsort-color child) 'gray) + (format t "~&Detected cycle containing ~A" child))))) + (setf (topsort-color node) 'black) + (setf (topsort-time node) time) + (incf time))) + (dolist (node list) + (setf (topsort-color node) 'white)) + (dolist (node list) + (when (eq (topsort-color node) 'white) + (dfs-visit node))) + (sort list #'< :key #'topsort-time))) + +;;; ******************************** +;;; Output to User ***************** +;;; ******************************** +;;; All output to the user is via the tell-user functions. + +(defun split-string (string &key (item #\space) (test #'char=)) + ;; Splits the string into substrings at spaces. + (let ((len (length string)) + (index 0) result) + (dotimes (i len + (progn (unless (= index len) + (push (subseq string index) result)) + (reverse result))) + (when (funcall test (char string i) item) + (unless (= index i);; two spaces in a row + (push (subseq string index i) result)) + (setf index (1+ i)))))) + +;; probably should remove the ",1" entirely. +(defun prompt-string (component) + (format nil "; ~:[~;TEST:~]~V,1@T " + *oos-test* + (component-indent component))) + +#| +(defun format-justified-string (prompt contents) + (format t (concatenate 'string "~%" prompt "-~{~<~%" prompt " ~1,80:; ~A~>~^~}") + (split-string contents)) + (finish-output *standard-output*)) +|# + +(defun format-justified-string (prompt contents &optional (width 80) + (stream *standard-output*)) + (let ((prompt-length (+ 2 (length prompt)))) + (cond ((< (+ prompt-length (length contents)) width) + (format stream "~%~A- ~A" prompt contents)) + (t + (format stream "~%~A-" prompt) + (do* ((cursor prompt-length) + (contents (split-string contents) (cdr contents)) + (content (car contents) (car contents)) + (content-length (1+ (length content)) (1+ (length content)))) + ((null contents)) + (cond ((< (+ cursor content-length) width) + (incf cursor content-length) + (format stream " ~A" content)) + (t + (setf cursor (+ prompt-length content-length)) + (format stream "~%~A ~A" prompt content))))))) + (finish-output stream)) + +(defun tell-user (what component &optional type no-dots force) + (when (or *oos-verbose* force) + (format-justified-string (prompt-string component) + (format nil "~A ~(~A~) ~@[\"~A\"~] ~:[~;...~]" + ;; To have better messages, wrap the following around the + ;; case statement: + ;;(if (find (component-type component) + ;; '(:defsystem :system :subsystem :module)) + ;; "Checking" + ;; (case ...)) + ;; This gets around the problem of DEFSYSTEM reporting + ;; that it's loading a module, when it eventually never + ;; loads any of the files of the module. + (case what + ((compile :compile) + (if (component-load-only component) + ;; If it is :load-only t, we're loading. + "Loading" + ;; Otherwise we're compiling. + "Compiling")) + ((load :load) "Loading") + (otherwise what)) + (component-type component) + (or (when type + (namestring-or-nil (component-full-pathname + component type))) + (component-name component)) + (and *tell-user-when-done* + (not no-dots)))))) + +(defun tell-user-done (component &optional force no-dots) + ;; test is no longer really used, but we're leaving it in. + (when (and *tell-user-when-done* + (or *oos-verbose* force)) + (format t "~&~A~:[~;...~] Done." + (prompt-string component) (not no-dots)) + (finish-output *standard-output*))) + +(defmacro with-tell-user ((what component &optional type no-dots force) &body body) + `(progn + (tell-user ,what ,component ,type ,no-dots ,force) + ,@body + (tell-user-done ,component ,force ,no-dots))) + +(defun tell-user-no-files (component &optional force) + (when (or *oos-verbose* force) + (format-justified-string (prompt-string component) + (format nil "Source file ~A ~ + ~:[and binary file ~A ~;~]not found, not loading." + (namestring (component-full-pathname component :source)) + (or *load-source-if-no-binary* *load-source-instead-of-binary*) + (namestring (component-full-pathname component :binary)))))) + +(defun tell-user-require-system (name parent) + (when *oos-verbose* + (format t "~&; ~:[~;TEST:~] - System ~A requires ~S" + *oos-test* (component-name parent) name) + (finish-output *standard-output*))) + +(defun tell-user-generic (string) + (when *oos-verbose* + (format t "~&; ~:[~;TEST:~] - ~A" + *oos-test* string) + (finish-output *standard-output*))) + +;;; ******************************** +;;; Y-OR-N-P-WAIT ****************** +;;; ******************************** +;;; y-or-n-p-wait is like y-or-n-p, but will timeout +;;; after a specified number of seconds +(defun internal-real-time-in-seconds () + (float (/ (get-internal-real-time) + internal-time-units-per-second))) + +(defun read-char-wait (&optional (timeout 20) input-stream &aux char) + (do ((start (internal-real-time-in-seconds))) + ((or (setq char (read-char-no-hang input-stream)) ;(listen *query-io*) + (< (+ start timeout) (internal-real-time-in-seconds))) + char))) + +;;; Lots of lisps, especially those that run on top of UNIX, do not get +;;; their input one character at a time, but a whole line at a time because +;;; of the buffering done by the UNIX system. This causes y-or-n-p-wait +;;; to not always work as expected. +;;; +;;; I wish lisp did all its own buffering (turning off UNIX input line +;;; buffering by putting the UNIX into CBREAK mode). Of course, this means +;;; that we lose input editing, but why can't the lisp implement this? + +(defvar *use-timeouts* t + "If T, timeouts in Y-OR-N-P-WAIT are enabled. Otherwise it behaves + like Y-OR-N-P. This is provided for users whose lisps don't handle + read-char-no-hang properly.") + +(defvar *clear-input-before-query* t + "If T, y-or-n-p-wait will clear the input before printing the prompt + and asking the user for input.") + +(defun y-or-n-p-wait (&optional (default #\y) (timeout 20) + format-string &rest args) + "Y-OR-N-P-WAIT prints the message, if any, and reads characters from + *QUERY-IO* until the user enters y, Y or space as an affirmative, or either + n or N as a negative answer, or the timeout occurs. It asks again if + you enter any other characters." + (when *clear-input-before-query* (clear-input *query-io*)) + (when format-string + (fresh-line *query-io*) + (apply #'format *query-io* format-string args) + ;; FINISH-OUTPUT needed for CMU and other places which don't handle + ;; output streams nicely. This prevents it from continuing and + ;; reading the query until the prompt has been printed. + (finish-output *query-io*)) + (loop + (let* ((read-char (if *use-timeouts* + (read-char-wait timeout *query-io*) + (read-char *query-io*))) + (char (or read-char default))) + ;; We need to ignore #\newline because otherwise the bugs in + ;; clear-input will cause y-or-n-p-wait to print the "Type ..." + ;; message every time... *sigh* + ;; Anyway, we might want to use this to ignore whitespace once + ;; clear-input is fixed. + (unless (find char '(#\tab #\newline #\return)) + (when (null read-char) + (format *query-io* "~@[~A~]" default) + (finish-output *query-io*)) + (cond ((null char) (return t)) + ((find char '(#\y #\Y #\space) :test #'char=) (return t)) + ((find char '(#\n #\N) :test #'char=) (return nil)) + (t + (when *clear-input-before-query* (clear-input *query-io*)) + (format *query-io* "~&Type \"y\" for yes or \"n\" for no. ") + (when format-string + (fresh-line *query-io*) + (apply #'format *query-io* format-string args)) + (finish-output *query-io*))))))) + +#| +(y-or-n-p-wait #\y 20 "What? ") +(progn (format t "~&hi") (finish-output) + (y-or-n-p-wait #\y 10 "1? ") + (y-or-n-p-wait #\n 10 "2? ")) +|# +;;; ******************************** +;;; Operate on System ************** +;;; ******************************** +;;; Operate-on-system +;; Operation is :compile, 'compile, :load or 'load +;; Force is :all or :new-source or :new-source-and-dependents or a list of +;; specific modules. +;; :all (or T) forces a recompilation of every file in the system +;; :new-source-and-dependents compiles only those files whose +;; sources have changed or who depend on recompiled files. +;; :new-source compiles only those files whose sources have changed +;; A list of modules means that only those modules and their dependents are recompiled. +;; Test is T to print out what it would do without actually doing it. +;; Note: it automatically sets verbose to T if test is T. +;; Verbose is T to print out what it is doing (compiling, loading of +;; modules and files) as it does it. +;; Dribble should be the pathname of the dribble file if you want to +;; dribble the compilation. +;; Load-source-instead-of-binary is T to load .lisp instead of binary files. +;; Version may be nil to signify no subdirectory, +;; a symbol, such as alpha, beta, omega, :alpha, mark, which +;; specifies a subdirectory of the root, or +;; a string, which replaces the root. +;; +(defun operate-on-system (name operation &key force + (version *version*) + (test *oos-test*) (verbose *oos-verbose*) + (load-source-instead-of-binary *load-source-instead-of-binary*) + (load-source-if-no-binary *load-source-if-no-binary*) + (bother-user-if-no-binary *bother-user-if-no-binary*) + (compile-during-load *compile-during-load*) + dribble + (minimal-load *minimal-load*)) + (unwind-protect + ;; Protect the undribble. + (progn + (when dribble (dribble dribble)) + (when test (setq verbose t)) + (when (null force);; defaults + (case operation + ((load :load) (setq force :all)) + ((compile :compile) (setq force :new-source-and-dependents)) + (t (setq force :all)))) + ;; Some CL implementations have a variable called *compile-verbose* + ;; or *compile-file-verbose*. + (multiple-value-bind (*version-dir* *version-replace*) + (translate-version version) + ;; CL implementations may uniformly default this to nil + (let ((*load-verbose* t) ; nil + ;; avoid warning from CMUcl compiler -- stolcke 9/18/92 + ;; KCL also doesn't about these -- stolcke 10/22/93 + #-(or :cmu :kcl :ECL) (*compile-file-verbose* t) ; nil + #-(or :kcl :ECL) (*compile-verbose* t) ; nil + (*version* version) + (*oos-verbose* verbose) + (*oos-test* test) + (*load-source-if-no-binary* load-source-if-no-binary) + (*compile-during-load* compile-during-load) + (*bother-user-if-no-binary* bother-user-if-no-binary) + (*load-source-instead-of-binary* load-source-instead-of-binary) + (*minimal-load* minimal-load) + (system (find-system name :load))) + (unless (component-operation operation) + (error "Operation ~A undefined." operation)) + (operate-on-component system operation force)))) + (when dribble (dribble)))) + +(defun COMPILE-SYSTEM (name &key force + (version *version*) + (test *oos-test*) (verbose *oos-verbose*) + (load-source-instead-of-binary *load-source-instead-of-binary*) + (load-source-if-no-binary *load-source-if-no-binary*) + (bother-user-if-no-binary *bother-user-if-no-binary*) + (compile-during-load *compile-during-load*) + dribble + (minimal-load *minimal-load*)) + ;; For users who are confused by OOS. + (operate-on-system + name :compile + :force force + :version version + :test test + :verbose verbose + :load-source-instead-of-binary load-source-instead-of-binary + :load-source-if-no-binary load-source-if-no-binary + :bother-user-if-no-binary bother-user-if-no-binary + :compile-during-load compile-during-load + :dribble dribble + :minimal-load minimal-load)) + +(defun LOAD-SYSTEM (name &key force + (version *version*) + (test *oos-test*) (verbose *oos-verbose*) + (load-source-instead-of-binary *load-source-instead-of-binary*) + (load-source-if-no-binary *load-source-if-no-binary*) + (bother-user-if-no-binary *bother-user-if-no-binary*) + (compile-during-load *compile-during-load*) + dribble + (minimal-load *minimal-load*)) + ;; For users who are confused by OOS. + (operate-on-system + name :load + :force force + :version version + :test test + :verbose verbose + :load-source-instead-of-binary load-source-instead-of-binary + :load-source-if-no-binary load-source-if-no-binary + :bother-user-if-no-binary bother-user-if-no-binary + :compile-during-load compile-during-load + :dribble dribble + :minimal-load minimal-load)) + +(defun operate-on-component (component operation force &aux changed) + ;; Returns T if something changed and had to be compiled. + (let ((type (component-type component)) + (old-package (package-name *package*))) + + (unwind-protect + ;; Protect old-package. + (progn + ;; Use the correct package. + (when (component-package component) + (tell-user-generic (format nil "Using package ~A" + (component-package component))) + (unless *oos-test* + (unless (find-package (component-package component)) + ;; If the package name is the same as the name of the system, + ;; and the package is not defined, this would lead to an + ;; infinite loop, so bomb out with an error. + (when (string-equal (string (component-package component)) + (component-name component)) + (format t "~%Component ~A not loaded:~%" + (component-name component)) + (error " Package ~A is not defined" + (component-package component))) + ;; If package not found, try using REQUIRE to load it. + (new-require (component-package component))) + ;; This was USE-PACKAGE, but should be IN-PACKAGE. + ;; Actually, CLtL2 lisps define in-package as a macro, + ;; so we'll set the package manually. + ;; (in-package (component-package component)) + (let ((package (find-package (component-package component)))) + (when package + (setf *package* package))))) + + ;; Load any required systems + (when (eq type :defsystem) ; maybe :system too? + (operate-on-system-dependencies component operation force)) + + ;; Do any initial actions + (when (component-initially-do component) + (tell-user-generic (format nil "Doing initializations for ~A" + (component-name component))) + (or *oos-test* + (eval (component-initially-do component)))) + + ;; If operation is :compile and load-only is T, this would change + ;; the operation to load. Only, this would mean that a module would + ;; be considered to have changed if it was :load-only and had to be + ;; loaded, and then dependents would be recompiled -- this doesn't + ;; seem right. So instead, we propagate the :load-only attribute + ;; to the components, and modify compile-file-operation so that + ;; it won't compile the files (and modify tell-user to say "Loading" + ;; instead of "Compiling" for load-only modules). + #|(when (and (find operation '(:compile compile)) + (component-load-only component)) + (setf operation :load))|# + + ;; Do operation and set changed flag if necessary. + (setq changed + (case type + ((:file :private-file) + (funcall (component-operation operation) component force)) + ((:module :system :subsystem :defsystem) + (operate-on-components component operation force changed)))) + + ;; Do any final actions + (when (component-finally-do component) + (tell-user-generic (format nil "Doing finalizations for ~A" + (component-name component))) + (or *oos-test* + (eval (component-finally-do component))))) + + ;; Reset the package. (Cleanup form of unwind-protect.) + ;;(in-package old-package) + (setf *package* (find-package old-package))) + + ;; Provide the loaded system + (when (or (eq type :defsystem) (eq type :system) (eq type :subsystem)) + (tell-user-generic (format nil "Providing system ~A" + (component-name component))) + (or *oos-test* + (provide (canonicalize-system-name (component-name component)))))) + + ;; Return t if something changed in this component and hence had to be recompiled. + changed) + +(defvar *force* nil) +(defvar *providing-blocks-load-propagation* t + "If T, if a system dependency exists on *modules*, it is not loaded.") +(defun operate-on-system-dependencies (component operation &optional force) + (when *system-dependencies-delayed* + (let ((*force* force)) + (dolist (system (component-depends-on component)) + ;; For each system that this system depends on, if it is a + ;; defined system (either via defsystem or component type :system), + ;; and propagation is turned on, propagates the operation to the + ;; subsystem. Otherwise runs require (my version) on that system + ;; to load it (needed since we may be depending on a lisp + ;; dependent package). + ;; Explores the system tree in a DFS manner. + (cond ((and *operations-propagate-to-subsystems* + (not (listp system)) + ;; The subsystem is a defined system. + (find-system system :load-or-nil)) + ;; Call OOS on it. Since *system-dependencies-delayed* is + ;; T, the :depends-on slot is filled with the names of + ;; systems, not defstructs. + ;; Aside from system, operation, force, for everything else + ;; we rely on the globals. + (unless (and *providing-blocks-load-propagation* + ;; If *providing-blocks-load-propagation* is T, + ;; the system dependency must not exist in the + ;; *modules* for it to be loaded. Note that + ;; the dependencies are implicitly systems. + (find operation '(load :load)) + ;; (or (eq force :all) (eq force t)) + (find (canonicalize-system-name system) + *modules* :test #'string=)) + (operate-on-system system operation :force force))) + ((listp system) + (tell-user-require-system + (cond ((and (null (car system)) (null (cadr system))) + (caddr system)) + (t system)) + component) + (or *oos-test* (new-require (car system) nil + (eval (cadr system)) + (caddr system) + (or (car (cdddr system)) + *version*)))) + (t + (tell-user-require-system system component) + (or *oos-test* (new-require system)))))))) + +(defun operate-on-components (component operation force changed) + (with-tell-user (operation component) + (if (component-components component) + (dolist (module (component-components component)) + (when (operate-on-component module operation + (cond ((and (dolist (dependent (component-depends-on module)) + (when (member dependent changed) + (return t))) + #|(some #'(lambda (dependent) + (member dependent changed)) + (component-depends-on module))|# + (or (non-empty-listp force) + (eq force :new-source-and-dependents))) + ;; The component depends on a changed file + ;; and force agrees. + (if (eq force :new-source-and-dependents) + :new-source-all + :all)) + ((and (non-empty-listp force) + (member (component-name module) force + :test #'string-equal :key #'string)) + ;; Force is a list of modules + ;; and the component is one of them. + :all) + (t force))) + (push module changed))) + (case operation + ((compile :compile) + (eval (component-compile-form component))) + ((load :load) + (eval (component-load-form component)))))) + changed) + +;;; ******************************** +;;; New Require ******************** +;;; ******************************** +(defvar *old-require* nil) + +;;; All calls to require in this file have been replaced with calls +;;; to new-require to avoid compiler warnings and make this less of +;;; a tangled mess. +(defun new-require (module-name &optional pathname definition-pname + default-action (version *version*)) + ;; If the pathname is present, this behaves like the old require. + (unless (and module-name + (find #-CMU (string module-name) + #+CMU (string-downcase (string module-name)) + *modules* :test #'string=)) + (cond (pathname + (funcall *old-require* module-name pathname)) + ;; If the system is defined, load it. + ((find-system module-name :load-or-nil definition-pname) + (operate-on-system module-name :load + :force *force* + :version version + :test *oos-test* + :verbose *oos-verbose* + :load-source-if-no-binary *load-source-if-no-binary* + :bother-user-if-no-binary *bother-user-if-no-binary* + :compile-during-load *compile-during-load* + :load-source-instead-of-binary *load-source-instead-of-binary* + :minimal-load *minimal-load*)) + ;; If there's a default action, do it. This could be a progn which + ;; loads a file that does everything. + ((and default-action + (eval default-action))) + ;; If no system definition file, try regular require. + ;; had last arg PATHNAME, but this wasn't really necessary. + ((funcall *old-require* module-name)) + ;; If no default action, print a warning or error message. + (t + (format t "~&Warning: System ~A doesn't seem to be defined..." + module-name))))) + +;;; Note that in some lisps, when the compiler sees a REQUIRE form at +;;; top level it immediately executes it. This is as if an +;;; (eval-when (compile load eval) ...) were wrapped around the REQUIRE +;;; form. I don't see any easy way to do this without making REQUIRE +;;; a macro. +;;; +;;; For example, in VAXLisp, if a (require 'streams) form is at the top of +;;; a file in the system, compiling the system doesn't wind up loading the +;;; streams module. If the (require 'streams) form is included within an +;;; (eval-when (compile load eval) ...) then everything is OK. +;;; +;;; So perhaps we should replace the redefinition of lisp:require +;;; with the following macro definition: +#| +(unless *old-require* + (setf *old-require* + (symbol-function #-(and :excl :allegro-v4.0) 'lisp:require + #+(and :excl :allegro-v4.0) 'cltl1:require)) + + (let (#+:CCL (ccl:*warn-if-redefine-kernel* nil)) + ;; Note that lots of lisps barf if we redefine a function from + ;; the LISP package. So what we do is define a macro with an + ;; unused name, and use (setf macro-function) to redefine + ;; lisp:require without compiler warnings. If the lisp doesn't + ;; do the right thing, try just replacing require-as-macro + ;; with lisp:require. + (defmacro require-as-macro (module-name + &optional pathname definition-pname + default-action (version '*version*)) + `(eval-when (compile load eval) + (new-require ,module-name ,pathname ,definition-pname + ,default-action ,version))) + (setf (macro-function #-(and :excl :allegro-v4.0) 'lisp:require + #+(and :excl :allegro-v4.0) 'cltl1:require) + (macro-function 'require-as-macro)))) +|# +;;; This will almost certainly fix the problem, but will cause problems +;;; if anybody does a funcall on #'require. + +;;; Redefine old require to call the new require. +(unless *old-require* + (setf *old-require* + (symbol-function #-(or (and :excl :allegro-v4.0) :mcl) 'lisp:require + #+(and :excl :allegro-v4.0) 'cltl1:require + #+:mcl 'ccl:require)) + + (unless *dont-redefine-require* + (let (#+:CCL (ccl:*warn-if-redefine-kernel* nil)) + (setf (symbol-function + #-(or (and :excl :allegro-v4.0) :mcl) 'lisp:require + #+(and :excl :allegro-v4.0) 'cltl1:require + #+:mcl 'ccl:require) + (symbol-function 'new-require))))) + + +;;; ******************************** +;;; Component Operations *********** +;;; ******************************** +;;; Define :compile/compile and :load/load operations +(component-operation :compile 'compile-and-load-operation) +(component-operation 'compile 'compile-and-load-operation) +(component-operation :load 'load-file-operation) +(component-operation 'load 'load-file-operation) + +(defun compile-and-load-operation (component force) + ;; FORCE was CHANGED. this caused defsystem during compilation to only + ;; load files that it immediately compiled. + (let ((changed (compile-file-operation component force))) + ;; Return T if the file had to be recompiled and reloaded. + (if (and changed (component-compile-only component)) + ;; For files which are :compile-only T, compiling the file + ;; satisfies the need to load. + changed + ;; If the file wasn't compiled, or :compile-only is nil, + ;; check to see if it needs to be loaded. + (and (load-file-operation component force) ; FORCE was CHANGED ??? + changed)))) + +(defun compile-file-operation (component force) + ;; Returns T if the file had to be compiled. + (let ((must-compile + ;; For files which are :load-only T, loading the file + ;; satisfies the demand to recompile. + (and (null (component-load-only component)) ; not load-only + (or (find force '(:all :new-source-all t) :test #'eq) + (and (find force '(:new-source :new-source-and-dependents) + :test #'eq) + (needs-compilation component)))))) + + (cond ((and must-compile + (probe-file (component-full-pathname component :source))) + (with-tell-user ("Compiling source" component :source) + (or *oos-test* + (compile-file (component-full-pathname component :source) + :output-file (component-full-pathname component :binary) + #+CMU :error-file #+CMU (and *cmu-errors-to-file* + (component-full-pathname component :error)) + #+(and CMU (not :new-compiler)) + :errors-to-terminal + #+(and CMU (not :new-compiler)) + *cmu-errors-to-terminal* + ))) + must-compile) + (must-compile + (tell-user "Source file not found. Not compiling" + component :source :no-dots :force) + nil) + (t nil)))) + +(defun needs-compilation (component) + ;; If there is no binary, or it is older than the source + ;; file, then the component needs to be compiled. + ;; Otherwise we only need to recompile if it depends on a file that changed. + (and + ;; source must exist + (probe-file (component-full-pathname component :source)) + (or + ;; no binary + (null (probe-file (component-full-pathname component :binary))) + ;; old binary + (< (file-write-date (component-full-pathname component :binary)) + (file-write-date (component-full-pathname component :source)))))) + +(defun needs-loading (component &optional (check-source t) (check-binary t)) + ;; Compares the component's load-time against the file-write-date of + ;; the files on disk. + (let ((load-time (component-load-time component))) + (or + ;; File never loaded. + (null load-time) + ;; Binary is newer. + (when (and check-binary + (probe-file (component-full-pathname component :binary))) + (< load-time + (file-write-date (component-full-pathname component :binary)))) + ;; Source is newer. + (when (and check-source + (probe-file (component-full-pathname component :source))) + (< load-time + (file-write-date (component-full-pathname component :source))))))) + +;;; Need to completely rework this function... +(defun load-file-operation (component force) + ;; Returns T if the file had to be loaded + (let* ((binary-pname (component-full-pathname component :binary)) + (source-pname (component-full-pathname component :source)) + (binary-exists (probe-file binary-pname)) + (source-exists (probe-file source-pname)) + (source-needs-loading (needs-loading component t nil)) + (binary-needs-loading (needs-loading component nil t)) + ;; needs-compilation has an implicit source-exists in it. + (needs-compilation (if (component-load-only component) + source-needs-loading + (needs-compilation component))) + (check-for-new-source + ;; If force is :new-source*, we're checking for files + ;; whose source is newer than the compiled versions. + (find force '(:new-source :new-source-and-dependents :new-source-all) + :test #'eq)) + (load-binary (or (find force '(:all :new-source-all t) :test #'eq) + binary-needs-loading)) + (load-source + (or *load-source-instead-of-binary* + (and load-binary (component-load-only component)) + (and check-for-new-source needs-compilation))) + (compile-and-load + (and needs-compilation (or load-binary check-for-new-source) + (compile-and-load-source-if-no-binary component)))) + ;; When we're trying to minimize the files loaded to only those + ;; that need be, restrict the values of load-source and load-binary + ;; so that we only load the component if the files are newer than + ;; the load-time. + (when *minimal-load* + (when load-source (setf load-source source-needs-loading)) + (when load-binary (setf load-binary binary-needs-loading))) + + (when (or load-source load-binary compile-and-load) + (cond (compile-and-load + ;; If we're loading the binary and it is old or nonexistent, + ;; and the user says yes, compile and load the source. + (compile-file-operation component t) + (with-tell-user ("Loading binary" component :binary) + (or *oos-test* + (progn + (load binary-pname) + (setf (component-load-time component) + (file-write-date binary-pname))))) + T) + ((and source-exists + (or (and load-source ; implicit needs-comp... + (or *load-source-instead-of-binary* + (component-load-only component) + (not *compile-during-load*))) + (and load-binary (not binary-exists) + (load-source-if-no-binary component)))) + ;; Load the source if the source exists and: + ;; o we're loading binary and it doesn't exist + ;; o we're forcing it + ;; o we're loading new source and user wasn't asked to compile + (with-tell-user ("Loading source" component :source) + (or *oos-test* + (progn + (load source-pname) + (setf (component-load-time component) + (file-write-date source-pname))))) + T) + ((and binary-exists load-binary) + (with-tell-user ("Loading binary" component :binary) + (or *oos-test* + (progn + (load binary-pname) + (setf (component-load-time component) + (file-write-date binary-pname))))) + T) + ((and (not binary-exists) (not source-exists)) + (tell-user-no-files component :force) + (when *files-missing-is-an-error* + (cerror "Continue, ignoring missing files." + "~&Source file ~S ~:[and binary file ~S ~;~]do not exist." + (namestring source-pname) + (or *load-source-if-no-binary* + *load-source-instead-of-binary*) + (namestring binary-pname))) + nil) + (t + nil))))) + +(component-operation :delete-binaries 'delete-binaries-operation) +(defun delete-binaries-operation (component force) + (when (or (eq force :all) + (eq force t) + (and (find force '(:new-source :new-source-and-dependents + :new-source-all) + :test #'eq) + (needs-compilation component))) + (when (probe-file (component-full-pathname component :binary)) + (with-tell-user ("Deleting binary" component :binary) + (or *oos-test* + (delete-file (component-full-pathname component :binary))))))) + + +;; when the operation = :compile, we can assume the binary exists in test mode. +;; ((and *oos-test* +;; (eq operation :compile) +;; (probe-file (component-full-pathname component :source))) +;; (with-tell-user ("Loading binary" component :binary))) + +(defun binary-exists (component) + (probe-file (component-full-pathname component :binary))) + +;;; or old-binary +(defun compile-and-load-source-if-no-binary (component) + (when (not (or *load-source-instead-of-binary* + (and *load-source-if-no-binary* + (not (binary-exists component))))) + (cond ((component-load-only component) + #|(let ((prompt (prompt-string component))) + (format t "~A- File ~A is load-only, ~ + ~&~A not compiling." + prompt + (namestring (component-full-pathname component :source)) + prompt))|# + nil) + ((eq *compile-during-load* :query) + (let* ((prompt (prompt-string component)) + (compile-source + (y-or-n-p-wait + #\y 30 + "~A- Binary file ~A is old or does not exist. ~ + ~&~A Compile (and load) source file ~A instead? " + prompt + (namestring (component-full-pathname component :binary)) + prompt + (namestring (component-full-pathname component :source))))) + (unless (y-or-n-p-wait + #\y 30 + "~A- Should I bother you if this happens again? " + prompt) + (setq *compile-during-load* + (y-or-n-p-wait + #\y 30 + "~A- Should I compile and load or not? " + prompt))) ; was compile-source, then t + compile-source)) + (*compile-during-load*) + (t nil)))) + +(defun load-source-if-no-binary (component) + (and (not *load-source-instead-of-binary*) + (or (and *load-source-if-no-binary* + (not (binary-exists component))) + (component-load-only component) + (when *bother-user-if-no-binary* + (let* ((prompt (prompt-string component)) + (load-source + (y-or-n-p-wait #\y 30 + "~A- Binary file ~A does not exist. ~ + ~&~A Load source file ~A instead? " + prompt + (namestring (component-full-pathname component :binary)) + prompt + (namestring (component-full-pathname component :source))))) + (setq *bother-user-if-no-binary* + (y-or-n-p-wait #\n 30 + "~A- Should I bother you if this happens again? " + prompt )) + (unless *bother-user-if-no-binary* + (setq *load-source-if-no-binary* load-source)) + load-source))))) + +;;; ******************************** +;;; Allegro Make System Fasl ******* +;;; ******************************** +#+:excl +(defun allegro-make-system-fasl (system destination) + (excl:shell + (format nil "rm -f ~A; cat~{ ~A~} > ~A" + destination + (mapcar #'namestring + (files-in-system system :all :binary))))) + +(defun files-which-need-compilation (system) + (mapcar #'(lambda (comp) (namestring (component-full-pathname comp :source))) + (remove nil + (file-components-in-component + (find-system system :load) :new-source)))) + +(defun files-in-system (name &optional (force :all) (type :source) version) + ;; Returns a list of the pathnames in system in load order. + (let ((system (find-system name :load))) + (multiple-value-bind (*version-dir* *version-replace*) + (translate-version version) + (let ((*version* version)) + (file-pathnames-in-component system type force))))) + +(defun file-pathnames-in-component (component type &optional (force :all)) + (mapcar #'(lambda (comp) (component-full-pathname comp type)) + (file-components-in-component component force))) + +(defun file-components-in-component (component &optional (force :all) + &aux result changed) + (case (component-type component) + ((:file :private-file) + (when (setq changed + (or (find force '(:all t) :test #'eq) + (and (not (non-empty-listp force)) + (needs-compilation component)))) + (setq result + (list component)))) + ((:module :system :subsystem :defsystem) + (dolist (module (component-components component)) + (multiple-value-bind (r c) + (file-components-in-component + module + (cond ((and (some #'(lambda (dependent) + (member dependent changed)) + (component-depends-on module)) + (or (non-empty-listp force) + (eq force :new-source-and-dependents))) + ;; The component depends on a changed file and force agrees. + :all) + ((and (non-empty-listp force) + (member (component-name module) force + :test #'string-equal :key #'string)) + ;; Force is a list of modules and the component is one of them. + :all) + (t force))) + (when c + (push module changed) + (setq result (append result r))))))) + (values result changed)) + +(setf (symbol-function 'oos) (symbol-function 'operate-on-system)) + +;;; ******************************** +;;; Additional Component Operations +;;; ******************************** + +;;; *** Edit Operation *** + +#+:ccl +(defun edit-operation (component force) + "Always returns nil, i.e. component not changed." + (declare (ignore force)) + ;; + (let* ((full-pathname (make::component-full-pathname component :source)) + (already-editing\? #+:mcl (dolist (w (windows :class 'fred-window)) + (when (equal (window-filename w) + full-pathname) + (return w))) + #-:mcl nil)) + (if already-editing\? + #+:mcl (window-select already-editing\?) #-:mcl nil + (ed full-pathname))) + nil) + +#+:ccl +(make::component-operation :edit 'edit-operation) +#+:ccl +(make::component-operation 'edit 'edit-operation) + +;;; *** System Source Size *** + +(defun system-source-size (system-name) + "Prints a short report and returns the size in bytes of the source files in + ." + (let* ((file-list (files-in-system system-name :all :source)) + (total-size (file-list-size file-list))) + (format t "~&~S (~A files) totals ~A bytes (~A K)" + system-name (length file-list) total-size (round total-size 1024)) + total-size)) + +(defun file-list-size (file-list) + "Returns the size in bytes of the files in ." + ;; + (let ((total-size 0)) + (dolist (file file-list) + (with-open-file (stream file) + (incf total-size (file-length stream)))) + total-size)) + + + +;;; **************************************************************** +;;; Dead Code ****************************************************** +;;; **************************************************************** + +#| +;;; ******************************** +;;; Alist Manipulation ************* +;;; ******************************** +;;; This is really gross. I've replaced it with hash tables. + +(defun alist-lookup (name alist &key (test #'eql) (key #'identity)) + (cdr (assoc name alist :test test :key key))) + +(defmacro set-alist-lookup ((name alist &key (test '#'eql) (key '#'identity)) + value) + (let ((pair (gensym))) + `(let ((,pair (assoc ,name ,alist :test ,test :key ,key))) + (if ,pair + (rplacd ,pair ,value) + (push (cons ,name ,value) ,alist))))) + +(defun component-operation (name &optional operation) + (if operation + (set-alist-lookup (name *component-operations*) operation) + (alist-lookup name *component-operations*))) + +(defun machine-type-translation (name &optional operation) + (if operation + (set-alist-lookup (name *machine-type-alist* :test #'string-equal) + operation) + (alist-lookup name *machine-type-alist* :test #'string-equal))) + +(defun software-type-translation (name &optional operation) + (if operation + (set-alist-lookup (name *software-type-alist* :test #'string-equal) + operation) + (alist-lookup name *software-type-alist* :test #'string-equal))) + +|# + +;;; *END OF FILE* + + + + diff --git a/contrib/metering.lsp b/contrib/metering.lsp new file mode 100644 index 000000000..136fb6212 --- /dev/null +++ b/contrib/metering.lsp @@ -0,0 +1,347 @@ +From daemon Fri Jul 8 22:43:26 1994 +>From clisp-list@ma2s2.mathematik.uni-karlsruhe.de Fri Jul 8 22:43:16 1994 +Return-Path: +Date: Fri, 8 Jul 94 22:45:40 +0200 +Errors-To: haible@ma2s2.mathematik.uni-karlsruhe.de +Originator: clisp-list@ma2s2.mathematik.uni-karlsruhe.de +Errors-To: haible@ma2s2.mathematik.uni-karlsruhe.de +Reply-To: clisp-list +Sender: clisp-list@ma2s2.mathematik.uni-karlsruhe.de +Version: 5.5 -- Copyright (c) 1991/92, Anastasios Kotsikonas +From: donc@ISI.EDU (Don Cohen) +To: Multiple recipients of list +Subject: recording function calls + + From: "Edward G. Kovach" + Is there a way to ... get a listing of.. + A. How many times a particular function is called? + B. How much time it takes to run each function? + +I've seen several such facilities. The one I like, though, is +my own, included below. At the cost of some extra space, it +records not only the number of calls and total time, but each +individual call, its inputs and outputs, its start/finish time. +This is much more useful for debugging and tuning, since you get +to see WHICH calls took a lot of time, which ones got the wrong +inputs or computed the wrong results, etc. + +;;; -*- Mode: LISP; Package: USER; Syntax: Common-lisp -*- +(lisp::in-package "USER") +; ---- Record the calls to given functions ---- +#| 2/17/89 - try to avoid advice, not so much because it's not commonlisp + as because it's not compiled! In fact, I want to be able to turn on and + off recording at high frequency and encapsulations seem to get in the way + of this. For now I'll assume that one does not encapsulate and record the + same functions. + + In order to monitor a function one first prepares it for monitoring, then + one can turn monitoring on and off at high frequency. One can also reset + or read the monitoring data for a function. Finally one can forget about + monitoring a function. + + *monitored-fns* is a list of functions currently prepared for monitoring. + (prepare-record-calls '(f1 f2 f3)) prepares the functions named. + additional keyword arguments: entryforms, exitforms, test + The entryforms are evaluated at function entry, the exitforms at function + exit. The results are recorded along with inputs, outputs, entry time + and exit time. Test is a form (default is T) that determines whether + this particular call will be recorded. It runs in an environment where + ARGS is bound to the argument list of the function. + (record-on '(f1 f2 f3)) turns on recording for these functions. + (record-off '(f1 f2 f3)) turns it off. + (initialize-records '(f1 f2 f3)) discards all monitoring data for the + functions (but does not turn recording off or on and does not forget + preparation). + (recorded-calls 'f1) returns a list of the call records for f1. + This is a list of records of the form + (inputs outputs start-time1 start-time2 end-time1 end-time2 + ) + Times are represented as 2 numbers since some clocks wrap around. + The second is a wrap around count that is incremented whenever the + finish time comes out lower than the start time. + (summarize-calls '(f1 f2 f3)) prints a summary of the calls. + The argument defaults to *monitored-fns*. + Additional optional argument: name-alist + Name-alist is something like ((f1 . "updating database") (f2 . "waiting")) + and is used to translate function names into something more meaningful. + (forget-record-calls '(f1 f2 f3)) discards all monitoring data and preparation + + (longest-n-calls 'f2 3) lists the 3 longest recorded calls of f2 + additional keyword arguments: start end filterfn + filterfn - a function of 1 arg (inputs outputs start finish) + should return T if the call is "interesting" + start/end are special cases - filter out anything that starts before start + or ends after end + + (time-line '(f1 f2 f3) produces a time line of activity + additional keyword arguments: (width 80) filterfn start end name-alist + + Both symbolics and TI have a fast short clock and a slow long one. + We use the fast one on symbolics, slow one on TI. + time before wrap around / #usec to read clock + -------------------------------------------- + symbolics 3600 TI explorer II + fast >.5 hour / 67 * 16 sec. / 260 + slow >100 yrs / 218 >1 hour / 260 * + + Actually we notice wrap around and record it - whenever a clock access + returns a smaller value than the previous one we increment a counter. + Therefore all events are ordered correctly, but if you fail to read the + clock for an hour or so, it's as if that time never passed. This is bad + if you time things on such a coarse scale, but good if you time one thing + for a minute today and something else for a minute tomorrow - the time + line between such events never separates them by much more than an hour. + In practice I don't think this will matter much. + + Since calls are recorded by pushing onto a list at exit, they are ordered + by decreasing exit time. This is handy for finding the outermost calls + in the case where the calls all come from the same process (and must thus + be properly nested). + (outermost (recorded-calls 'foo)) + returns the subset of the calls to foo that are outermost. + +|# + +(defvar *monitored-fns* nil) +(defvar *clock-cycle* 0) +(defvar *last-time* 0) +(defun prepare-record-calls (fns &key entryforms exitforms (test t)) + (loop for fn in fns do (prepare-record-call fn entryforms exitforms test))) + +; record-calls-fn prop is cons substitute and original fns +(defun prepare-record-call (fn entryforms exitforms test &aux prop) + (cond ((not (fboundp fn)) (error "no such function as ~A" fn)) + #+zetalisp + ((and (si:function-encapsulated-p fn) + (warn "~A is an encapsulation") nil)) + #+ignore ; might be called with different entryforms/exitforms + ((and (setf prop (get fn 'record-calls-fn)) + (eq (cdr prop) (symbol-function fn))) + #+ignore (warn "~A already recorded" fn)) + ((eq (symbol-function fn) (car prop)) + #+ignore (warn "~A already prepared" fn)) + (t ; not cached ... + (setf (get fn 'record-calls-fn) + (cons (make-record-fn fn entryforms exitforms test) + (symbol-function fn))) + (pushnew fn *monitored-fns*)))) + +(defun make-record-fn (fn entryforms exitforms test) + (compile nil + `(lambda (&rest args &aux start start1 values finish finish1 entryvals) + (if ,test + (unwind-protect + (progn (setq entryvals (list ,@entryforms) + start (microsec-time) + start1 *clock-cycle* + values (multiple-value-list + (apply ',(symbol-function fn) args)) + finish (microsec-time) finish1 *clock-cycle*) + (values-list values)) + (record-1-call ',fn (copy-list args) + (if finish values :abnormal-exit) + start start1 + (or finish (microsec-time)) + (or finish1 *clock-cycle*) + entryvals + (list ,@exitforms))) + (apply ',(symbol-function fn) args))))) +; perhaps we should try to correct for the time spent in the new function? + +(defun forget-record-calls (fns) + (record-off fns) + (loop for fn in fns do + (setq *monitored-fns* (delete fn *monitored-fns*)) + (setf (get fn 'record-calls-fn) nil) + (setf (get fn 'recorded-calls) nil))) + +(defun record-on (fns) + (loop for fn in fns do + (let ((prop (get fn 'record-calls-fn))) + (cond ((not prop) (cerror "skip turning on recording" + "~A not prepared for recording" fn)) + ((eq (cdr prop) (symbol-function fn)) + (setf (symbol-function fn) (car prop))) + ((eq (car prop) (symbol-function fn))) + (t (cerror "skip turning on recording" + "~A has changed since last prepared for recording" + fn)))))) + +(defun record-off (fns) + (loop for fn in fns do + (let ((prop (get fn 'record-calls-fn))) + (cond ((not prop) + (cerror "continue" "~A not prepared for recording" fn)) + ((eq (car prop) (symbol-function fn)) + (setf (symbol-function fn) (cdr prop))) + ((eq (cdr prop) (symbol-function fn))) + (t (cerror "continue" + "~A has changed since recording last turned on" + fn)))))) + +(defun microsec-time (&aux time) + (setq time + #-(or symbolics ti) (get-internal-run-time) + #+symbolics (time:fixnum-microsecond-time) + #+TI (time:microsecond-time)) + (when (< time *last-time*) (incf *clock-cycle*)) + (setf *last-time* time)) + +(defun record-1-call (fn inputs results t1 t11 t2 t21 entryvals exitvals) + (push (list inputs results t1 t11 t2 t21 entryvals exitvals) + (get fn 'recorded-calls))) + +(defun initialize-records (fns) + (loop for fn in fns do (setf (get fn 'recorded-calls) nil))) + +(defun recorded-calls (fn) (get fn 'recorded-calls)) + +(defun summarize-calls (&optional (fns *monitored-fns*) name-alist) + (loop for fn in fns do + (summarize-record fn (get fn 'recorded-calls) name-alist))) + +(defun summarize-record (fn calls name-alist) + (when calls (loop for x in calls sum 1 into ncalls + sum (elapsed (third x) (fourth x) (fifth x) (sixth x)) + into time finally + (print-summarize-record fn ncalls time name-alist)))) + +(defun print-summarize-record (fn ncalls time name-alist) + (multiple-value-bind (total tunits) + (standardized-time-units time) + (multiple-value-bind (avg aunits) + (standardized-time-units (float (/ time ncalls))) + (format *standard-output* "~%~A: ~A calls, ~A ~A (avg. ~A~:[ ~a~; ~])" + (or (cdr (assoc fn name-alist)) fn) + ncalls total tunits avg (eq aunits tunits) aunits)))) + +(defun standardized-time-units (usec) + (cond ((> usec 999999) (values (float (/ usec 1000000)) "sec.")) + ((> usec 999) (values (float (/ usec 1000)) "msec.")) + (t (values usec "usec.")))) + +(defun elapsed (t1 t11 t2 t21) + (+ (- t2 t1) (* (- t21 t11) (* 1024 1024 2048 #+TI 2)))) + +(defun longest-n-calls (fn n &key start end filterfn + &aux next time current + (candidates (recorded-calls fn)) (i 0)) + ; filterfn decides whether a record is "interesting" + ; special cases: start/end filters out anything that starts before start + ; or ends after end + (flet ((filter (e) (and (or (null start) + (plusp (elapsed start 0 (third e) (fourth e)))) + (or (null end) + (plusp (elapsed (fifth e) (sixth e) end 0))) + (or (null filterfn) (funcall filterfn e))))) + (loop while (and (< i n) (setq next (pop candidates))) + when (filter next) + do (incf i) (push (cons (elapsed (third next) (fourth next) + (fifth next) (sixth next)) + next) current)) + (setq current (sort current #'<= :key #'car)) + (loop while (setq next (pop candidates)) + when (filter next) + when (< (caar current) + (setq time (elapsed (third next) (fourth next) + (fifth next) (sixth next)))) + do (setq current (merge 'list (cdr current) + (list (cons time next)) + #'<= :key #'car))) + (nreverse current))) + +(defvar *time-line-key* + "Start time = ~A, End time = ~A, Width = ~A, ~ + ~& each column represents ~A ~A~ + ~& Key: ( = 1 entry, ) = 1 exit, * = more than one entry/exit~ + ~& if no entry/exit, a digit indicates number of active calls,~ + ~& blank indicates no change, + indicates >9 ~% ") + +(defun time-line (fns &key (width 80) filterfn start end len name-alist + &aux events) + (flet ((filter (e) (and (or (null start) + (plusp (elapsed start 0 (third e) (fourth e)))) + (or (null end) + (plusp (elapsed (fifth e) (sixth e) end 0))) + (or (null filterfn) (funcall filterfn e))))) + (setq events (loop for f in fns collect + (cons f (loop for e in (recorded-calls f) + when (filter e) collect e)))) + (unless (and start end) + (loop for e in events do + (loop for r in (cdr e) do + (when (or (null start) + (minusp (elapsed start 0 (third r) (fourth r)))) + (setq start (totalt (third r) (fourth r)))) + (when (or (null end) + (minusp (elapsed (fifth r) (sixth r) end 0))) + (setq end (totalt (fifth r) (sixth r))))))) + (when (and start end) (setq len (- end start))) + (unless (and len (> len 0)) (return-from time-line "empty interval")) + (multiple-value-bind (number unit) + (when (and start end width) + (standardized-time-units (/ (- end start 0.0) width))) + (apply #'concatenate 'string + (format nil *time-line-key* start end width number unit) + (loop for f in events collect + (concatenate 'string + (let ((string (make-string width + :initial-element #\space)) + index + (countstart + (make-array (list width) + :initial-element 0 + :element-type 'integer)) + (countend + (make-array (list width) :initial-element 0 + :element-type 'integer))) + (loop for e in (cdr f) do + (setq index + (min (1- width) + (floor (* width (/ (- (totalt (third e) + (fourth e)) + start) + len))))) + (incf (aref countstart index)) + (setf (aref string index) + (if (char= #\space (aref string index)) + #\( #\*)) + (setq index + (min (1- width) + (floor (* width (/ (- (totalt (fifth e) + (sixth e)) + start) + len))))) + (decf (aref countend index)) + (setf (aref string index) + (if (char= #\space (aref string index)) + #\) #\*))) + (loop for i below width with sum = 0 do + (setf sum (+ sum (aref countstart i) + (aref countend i))) + (when (and (/= i 0) + (/= (aref countstart (1- i)) 0) + (/= (aref countend (1- i)) 0) + (char= #\space (aref string i)) + (> sum 0)) + (setf (aref string i) + (if (> sum 9) #\+ (aref "0123456789" sum))))) + string) + (format nil " ~A~& " + (symbol-name (or (cdr (assoc (car f) name-alist)) + (car f)))))))))) + + +(defun outermost (calls &aux outer) + (loop for c in calls + unless (and outer (<= (totalt (third outer) (fourth outer)) + (totalt (third c) (fourth c)) + (totalt (fifth c) (sixth c)) + (totalt (fifth outer) (sixth outer)))) + collect (setf outer c))) + +; get the time represented by the two numbers x (low order) and y (high order) +(defun totalt (x y) (elapsed 0 0 x y)) + + + diff --git a/contrib/pvm/eclreader.lsp b/contrib/pvm/eclreader.lsp new file mode 100644 index 000000000..8ea7c9ecf --- /dev/null +++ b/contrib/pvm/eclreader.lsp @@ -0,0 +1,129 @@ +;;;-*-Mode: LISP; Syntax: Common LISP; Base: 10-*- +;;; +;;; File = eclreader.lsp +;;; Definition of reader for ECoLISP. +;;; +;;; (c) 1994, I.D. Alexander-Craig, all rights reserved. +;;; +;;; + + + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; Definition of the basic reader that is needed by KCL. ;;;; +;;;; The following function should be called when loading the ;;;; +;;;; object reader for KCL. This is called the default reader ;;;; +;;;; for KCL. ;;;; +;;;; ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +(defparameter *default-reader* ()) + +(defparameter *default-reader-specs* + (list + (list 'NULL + LISP_NIL_TYPE + * + #'(lambda (rdr) + (declare (ignore rdr)) + ())) + (list T + LISP_T_TYPE + '* + #'(lambda (rdr) + (declare (ignore rdr)) + t)) + (list 'STANDARD-CHAR ;; CHARACTER + LISP_CHAR_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (C-obuffer-char obj)) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-char))) + (list 'FIXNUM + LISP_INT_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (C-obuffer-int obj)) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-int))) + (list 'BIGNUM + LISP_LONGINT_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (C-obuffer-longint obj)) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-longint))) + (list 'LONG-FLOAT ;;FLOAT + LISP_DOUBLE_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (C-obuffer-double obj)) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-double))) + (list 'SYMBOL + LISP_SYMBOL_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (cond ((eq obj t) + (C-obuffer-t)) + ((null obj) + (C-obuffer-nil)) + (t + (let ((pname (symbol-name obj))) + (C-obuffer-symbol pname (length pname)))))) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-symbol))) + (list 'STRING ;; SIMPLE-STRING + LISP_STRING_TYPE + #'(lambda (obj rdr) + (declare (ignore rdr)) + (C-obuffer-string obj (length obj))) + #'(lambda (rdr) + (declare (ignore rdr)) + (C-ibuffer-string))) + (list 'VECTOR + LISP_VECTOR_TYPE + #'(lambda (obj rdr) + (encode-vector obj rdr)) + #'(lambda (rdr) + (decode-vector rdr))) + (list 'CONS + LISP_LIST_TYPE + #'(lambda (obj rdr) + (encode-list obj rdr)) + #'(lambda (rdr) + (decode-list rdr))))) + +;; For testing only: + +(defparameter *rdr* ()) + +(defun init-default-reader () + (setq *default-reader* (make-object-reader)) + (initialise-reader-object + *default-reader* + *default-reader-specs*) + (values)) + +(format t "Creating reader:~%") +(init-default-reader) +(format t "Done.~%~%") + +;;; For testing only: + +(setq *rdr* *default-reader*) + +(defun restart-reader () + (setq *default-reader* () + rdr ()) + (init-default-reader) + (setq *rdr* *default-reader*) + (values)) diff --git a/contrib/pvm/hostfile b/contrib/pvm/hostfile new file mode 100644 index 000000000..dd06e6a42 --- /dev/null +++ b/contrib/pvm/hostfile @@ -0,0 +1,2 @@ +database +igor diff --git a/contrib/pvm/load.lsp b/contrib/pvm/load.lsp new file mode 100644 index 000000000..2dd46e305 --- /dev/null +++ b/contrib/pvm/load.lsp @@ -0,0 +1,11 @@ +;;;-*-Mode: LISP; Syntax: Common LISP; Base: 10-*- +;;; +;;; File = load.lsp +;;; Load file for ECL<->PVM interface modules. +;;; + +(load "pvmconsts") +(load "pvmlisp") +(si:faslink "pvmecl" "-L/project/pvm/pvm3/lib/SUN4 -lgpvm3 -lpvm3 -lc") +;(load "pvmecl") +(load "eclreader") diff --git a/contrib/pvm/pvm-test.lsp b/contrib/pvm/pvm-test.lsp new file mode 100644 index 000000000..2c2f7354e --- /dev/null +++ b/contrib/pvm/pvm-test.lsp @@ -0,0 +1,14 @@ +(defparameter *my-tid* ()) + +(defun enroll () + (setq *my-tid* (lpvm-my-tid))) + +(defun leave () + (lpvm-exit) + (quit)) + +(defun send-rec (msg msgtype) + (format t "about to send~%") + (lpvm-send-message msg *rdr* msgtype *my-tid*) + (format t "about to receive~%") + (lpvm-nonblocking-recv *rdr* *my-tid* msgtype)) diff --git a/contrib/pvm/pvmconsts.lsp b/contrib/pvm/pvmconsts.lsp new file mode 100644 index 000000000..98ed6676f --- /dev/null +++ b/contrib/pvm/pvmconsts.lsp @@ -0,0 +1,109 @@ +;;;-*- Mode: LISP; Syntax: Common LISP; Base: 10 -*- +;;; +;;; File = pvmconsts.lisp +;;; +;;; PVM constant definitions. +;;; + +;; +;; Change log. +;; 25 March 1994. LISP_X_TYPE constants have contiguous values. +;; This is to support the new representation for the read structure. +;; + +;;; +;;; Constant definitions for type tags used to define +;;; message boundaries. +;;; The tags are all ad hoc and tailored to the needs of LISP. +;;; Each is represented by an integer. +;;; +;;; + +(defconstant MESSAGE_START 1) + ;; This says that there is going to be + ;; a new structure type that follows. +(defconstant LISP_NIL_TYPE 2) ; encode nil +(defconstant LISP_T_TYPE 3) ; encode t +(defconstant LISP_CHAR_TYPE 4) +(defconstant LISP_SHORTINT_TYPE 5) +(defconstant LISP_INT_TYPE 6) +(defconstant LISP_LONGINT_TYPE 7) +;(defconstant LISP_FLOAT_TYPE 8) not used in ECo or KCL +(defconstant LISP_DOUBLE_TYPE 9) +(defconstant LISP_SYMBOL_TYPE 10) +(defconstant LISP_STRING_TYPE 11) +(defconstant LISP_VECTOR_TYPE 12) +(defconstant LISP_LIST_TYPE 13) + ;; If complex and rational are required, we can fit them in. +(defconstant LISP_OPAQUE_TYPE 14) +(defconstant LISP_MIN_USER_TYPE 15) + + +;;; +;;; PVM constant definitions for error messages, together +;;; with the error function for PVM routines. +;;; + +(defconstant %PvmOk 0) +(defconstant %PvmBadParam -2) +(defconstant %PvmMismatch -3) +(defconstant %PvmNoData -5) +(defconstant %PvmNoHost -6) +(defconstant %PvmNoFile -7) +(defconstant %PvmNoMem -10) +(defconstant %PvmBadMsg -12) +(defconstant %PvmSysErr -14) +(defconstant %PvmNoBuf -15) +(defconstant %PvmNoSuchBuf -16) +(defconstant %PvmNullGroup -17) +(defconstant %PvmDupGroup -18) +(defconstant %PvmNoGroup -19) +(defconstant %PvmNotInGroup -20) +(defconstant %PvmNoInst -21) +(defconstant %PvmHostFail -22) +(defconstant %PvmNoParent -23) +(defconstant %PvmNotImpl -24) +(defconstant %PvmDSysErr -25) +(defconstant %PvmBadVersion -26) +(defconstant %PvmOutOfRes -27) +(defconstant %PvmDupHost -28) +(defconstant %PvmCantStart -29) +(defconstant %PvmAlready -30) +(defconstant %PvmNoTask -31) +(defconstant %PvmNoEntry -32) +(defconstant %PvmDupEntry -33) + + +(defun pvm-error (errno where) + ;; quick hack for testing + (unless (= errno %PvmOk) + (error "PVM error in ~s no. ~d~%" where errno))) + + +;;; +;;; Constants for pvm_advise +;;; + +(defconstant %PvmDontRoute 1) +(defconstant %PvmAllowDirect 2) +(defconstant %PvmRouteDirect 3) + +;;; +;;; Constants for pvm_initsend's encoding +;;; + +(defconstant %PvmDataDefault 0) ; use XDR if heterogeneous +(defconstant %PvmDataRaw 1) ; no encoding +(defconstant %PvmDataInPlace 2) ; leave data in place. + +;;; +;;; Constants for pvm_spawn. +;;; See the PVM manual p. 13 for details. +;;; + +(defconstant %PvmTaskDefault 0) +(defconstant %PvmTaskHost 1) +(defconstant %PvmTaskArch 2) +(defconstant %PvmTaskDebug 4) +(defconstant %PvmTaskTrace 8) + diff --git a/contrib/pvm/pvmecl.c b/contrib/pvm/pvmecl.c new file mode 100644 index 000000000..2ba3ba0d6 --- /dev/null +++ b/contrib/pvm/pvmecl.c @@ -0,0 +1,1058 @@ + +#include "pvmecl.h" +init_code(int size, object data_stream) +{VT2 CLSR2 + volatile object VVprotect; + Cblock.cd_start=(char *)init_code; Cblock.cd_size=size; + VVprotect=Cblock.cd_data=read_VV(VV,VM1,data_stream); + MF0(VV[95],L1); + (void)putprop(VV[95],VV[Vdeb95],VV[96]); + MF0(VV[2],L2); + funcall(2,VV[97]->s.s_gfdef,VV[1]) /* PROCLAIM */; + putprop(VV[2],VV[4],VV[3]); + MF0(VV[98],L3); + (void)putprop(VV[98],VV[Vdeb98],VV[96]); + MF0(VV[99],L4); + (void)putprop(VV[99],VV[Vdeb99],VV[96]); + MF0(VV[100],L5); + (void)putprop(VV[100],VV[Vdeb100],VV[96]); + MF0(VV[101],L6); + (void)putprop(VV[101],VV[Vdeb101],VV[96]); + MF0(VV[8],L7); + funcall(2,VV[97]->s.s_gfdef,VV[7]) /* PROCLAIM */; + putprop(VV[8],VV[9],VV[3]); + MF0(VV[102],L8); + (void)putprop(VV[102],VV[Vdeb102],VV[96]); + MF0(VV[103],L9); + (void)putprop(VV[103],VV[Vdeb103],VV[96]); + MF0(VV[13],L10); + funcall(2,VV[97]->s.s_gfdef,VV[12]) /* PROCLAIM */; + putprop(VV[13],VV[14],VV[3]); + MF0(VV[104],L11); + (void)putprop(VV[104],VV[Vdeb104],VV[96]); + MF0(VV[17],L12); + funcall(2,VV[97]->s.s_gfdef,VV[16]) /* PROCLAIM */; + putprop(VV[17],VV[18],VV[3]); + MF0(VV[105],L13); + (void)putprop(VV[105],VV[Vdeb105],VV[96]); + MF0(VV[21],L14); + funcall(2,VV[97]->s.s_gfdef,VV[20]) /* PROCLAIM */; + putprop(VV[21],VV[22],VV[3]); + MF0(VV[106],L15); + (void)putprop(VV[106],VV[Vdeb106],VV[96]); + MF0(VV[107],L16); + (void)putprop(VV[107],VV[Vdeb107],VV[96]); + MF0(VV[108],L17); + (void)putprop(VV[108],VV[Vdeb108],VV[96]); + MF0(VV[109],L18); + (void)putprop(VV[109],VV[Vdeb109],VV[96]); + MF0(VV[110],L19); + MF0(VV[111],L20); + (void)putprop(VV[111],VV[Vdeb111],VV[96]); + MF0(VV[112],L21); + (void)putprop(VV[112],VV[Vdeb112],VV[96]); + MF0(VV[113],L21); + (void)putprop(VV[113],VV[Vdeb113],VV[96]); + MF0(VV[114],L23); + MF0(VV[115],L24); + (void)putprop(VV[115],VV[Vdeb115],VV[96]); + MF0(VV[116],L25); + MF0(VV[117],L26); + (void)putprop(VV[117],VV[Vdeb117],VV[96]); + MF0(VV[118],L27); + MF0(VV[119],L28); + (void)putprop(VV[119],VV[Vdeb119],VV[96]); + MF0(VV[120],L29); + MF0(VV[121],L30); + (void)putprop(VV[121],VV[Vdeb121],VV[96]); + MF0(VV[122],L31); + (void)putprop(VV[122],VV[Vdeb122],VV[96]); + MF0(VV[123],L32); + MF0(VV[124],L33); + (void)putprop(VV[124],VV[Vdeb124],VV[96]); + MF0(VV[125],L34); + (void)putprop(VV[125],VV[Vdeb125],VV[96]); + MF0(VV[126],L35); + (void)putprop(VV[126],VV[Vdeb126],VV[96]); + MF0(VV[127],L36); + (void)putprop(VV[127],VV[Vdeb127],VV[96]); + MF0(VV[34],L37); + funcall(2,VV[97]->s.s_gfdef,VV[33]) /* PROCLAIM */; + putprop(VV[34],VV[35],VV[3]); + MF0(VV[128],L38); + (void)putprop(VV[128],VV[Vdeb128],VV[96]); + MF0(VV[40],L39); + funcall(2,VV[97]->s.s_gfdef,VV[39]) /* PROCLAIM */; + putprop(VV[40],VV[41],VV[3]); + MF0(VV[129],L40); + (void)putprop(VV[129],VV[Vdeb129],VV[96]); + MF0(VV[130],L41); + (void)putprop(VV[130],VV[Vdeb130],VV[96]); + MF0(VV[45],L42); + funcall(2,VV[97]->s.s_gfdef,VV[44]) /* PROCLAIM */; + putprop(VV[45],VV[46],VV[3]); + MF0(VV[131],L43); + (void)putprop(VV[131],VV[Vdeb131],VV[96]); + MF0(VV[50],L44); + funcall(2,VV[97]->s.s_gfdef,VV[49]) /* PROCLAIM */; + putprop(VV[50],VV[51],VV[3]); + MF0(VV[132],L45); + (void)putprop(VV[132],VV[Vdeb132],VV[96]); + MF0(VV[54],L46); + funcall(2,VV[97]->s.s_gfdef,VV[53]) /* PROCLAIM */; + putprop(VV[54],VV[55],VV[3]); + MF0(VV[133],L47); + (void)putprop(VV[133],VV[Vdeb133],VV[96]); + MF0(VV[58],L48); + funcall(2,VV[97]->s.s_gfdef,VV[57]) /* PROCLAIM */; + putprop(VV[58],VV[59],VV[3]); + MF0(VV[134],L49); + (void)putprop(VV[134],VV[Vdeb134],VV[96]); + MF0(VV[62],L50); + funcall(2,VV[97]->s.s_gfdef,VV[61]) /* PROCLAIM */; + putprop(VV[62],VV[63],VV[3]); + MF0(VV[135],L51); + (void)putprop(VV[135],VV[Vdeb135],VV[96]); + MF0(VV[66],L52); + funcall(2,VV[97]->s.s_gfdef,VV[65]) /* PROCLAIM */; + putprop(VV[66],VV[67],VV[3]); + MF0(VV[136],L53); + (void)putprop(VV[136],VV[Vdeb136],VV[96]); + MF0(VV[70],L54); + funcall(2,VV[97]->s.s_gfdef,VV[69]) /* PROCLAIM */; + putprop(VV[70],VV[71],VV[3]); + MF0(VV[137],L55); + (void)putprop(VV[137],VV[Vdeb137],VV[96]); + MF0(VV[74],L56); + funcall(2,VV[97]->s.s_gfdef,VV[73]) /* PROCLAIM */; + putprop(VV[74],VV[75],VV[3]); + MF0(VV[138],L57); + (void)putprop(VV[138],VV[Vdeb138],VV[96]); + MF0(VV[139],L58); + MF0(VV[140],L59); + (void)putprop(VV[140],VV[Vdeb140],VV[96]); + MF0(VV[88],L60); + funcall(2,VV[97]->s.s_gfdef,VV[87]) /* PROCLAIM */; + putprop(VV[88],VV[89],VV[3]); + MF0(VV[141],L61); + (void)putprop(VV[141],VV[Vdeb141],VV[96]); + MF0(VV[92],L62); + funcall(2,VV[97]->s.s_gfdef,VV[91]) /* PROCLAIM */; + putprop(VV[92],VV[93],VV[3]); + MF0(VV[142],L63); + (void)putprop(VV[142],VV[Vdeb142],VV[96]); + Cblock.cd_start=(char *)end_init; + Cblock.cd_size-=(char *)end_init - (char *)init_code; + insert_contblock((char *)init_code,(char *)end_init - (char *)init_code); +} +static end_init() {} +/* function definition for PVM-ERROR */ +static L1(int narg, object V1, object V2) +{ VT3 VLEX3 CLSR3 +TTL: + RETURN(Lerror(3,VV[0],(V1),(V2)) /* ERROR */); +} + +#include "/project/pvm/pvm3/include/pvm3.h" + +/* function definition for C_PVM_PKINT */ +static L2(int narg, object V1) +{ + int x; + x=pvm_pkint(&object_to_int(V1),1,1); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for OBUFFER-INT */ +static L3(int narg, object V1) +{ VT4 VLEX4 CLSR4 +TTL: + {int V2; /* INFO */ + V2= pvm_pkint(&fix((V1)),1,1); + if((0)==(V2)){ + goto L35;} + L1(2,MAKE_FIXNUM(V2),VV[5]) /* PVM-ERROR */; + } +L35: + RETURN(0); +} +/* function definition for PACK-TYPE-TAG */ +static L4(int narg, object V1) +{ VT5 VLEX5 CLSR5 +TTL: + {int V2; /* RETURN-CODE */ + V2= pvm_pkint(&fix((V1)),1,1); + if((0)==(V2)){ + goto L39;} + L1(2,MAKE_FIXNUM(V2),VV[6]) /* PVM-ERROR */; + } +L39: + RETURN(0); +} +/* function definition for C-OBUFFER-NIL */ +static L5(int narg) +{ VT6 VLEX6 CLSR6 +TTL: + RETURN(L4(1,MAKE_FIXNUM(2)) /* PACK-TYPE-TAG */); +} +/* function definition for C-OBUFFER-T */ +static L6(int narg) +{ VT7 VLEX7 CLSR7 +TTL: + RETURN(L4(1,MAKE_FIXNUM(3)) /* PACK-TYPE-TAG */); +} +/* function definition for C_PVM_PKCHAR */ +static L7(int narg, object V1) +{ + int x; + x=pvm_pkbyte(&object_to_char(V1),1,1); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for C-OBUFFER-CHAR */ +static L8(int narg, object V1) +{ VT8 VLEX8 CLSR8 +TTL: + L4(1,MAKE_FIXNUM(4)) /* PACK-TYPE-TAG */; + {int V2; /* INFO */ + V2= pvm_pkbyte(&char_code((V1)),1,1); + if((0)==(V2)){ + goto L44;} + L1(2,MAKE_FIXNUM(V2),VV[10]) /* PVM-ERROR */; + } +L44: + RETURN(0); +} +/* function definition for C-OBUFFER-INT */ +static L9(int narg, object V1) +{ VT9 VLEX9 CLSR9 +TTL: + L4(1,MAKE_FIXNUM(6)) /* PACK-TYPE-TAG */; + {int V2; /* INFO */ + V2= pvm_pkint(&fix((V1)),1,1); + if((0)==(V2)){ + goto L49;} + L1(2,MAKE_FIXNUM(V2),VV[11]) /* PVM-ERROR */; + } +L49: + RETURN(0); +} +/* function definition for C_PVM_PKFLOAT */ +static L10(int narg, object V1) +{ + int x; + x=pvm_pkfloat(&object_to_float(V1),1,1); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for OBUFFER-FLOAT */ +static L11(int narg, object V1) +{ VT10 VLEX10 CLSR10 +TTL: + {int V2; /* INFO */ + V2= pvm_pkfloat(&sf((V1)),1,1); + if((0)==(V2)){ + goto L53;} + L1(2,MAKE_FIXNUM(V2),VV[15]) /* PVM-ERROR */; + } +L53: + RETURN(0); +} +/* function definition for C_PVM_PKDOUBLE */ +static L12(int narg, object V1) +{ + int x; + x=pvm_pkdouble(&object_to_double(V1),1,1); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for C-OBUFFER-DOUBLE */ +static L13(int narg, object V1) +{ VT11 VLEX11 CLSR11 +TTL: + {int V2; /* INFO */ + V2= pvm_pkdouble(&lf((V1)),1,1); + if((0)==(V2)){ + goto L57;} + L1(2,MAKE_FIXNUM(V2),VV[19]) /* PVM-ERROR */; + } +L57: + RETURN(0); +} +/* function definition for C_PVM_PKSTR */ +static L14(int narg, object V1, object V2) +{ + int x; + x=(((object_to_int(V2) = pvm_pkint(&type,1,1)) == PvmOk) ? + pvm_pkstr((V1)->st.st_self) : object_to_int(V2)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for C-OBUFFER-SYMBOL */ +static L15(int narg, object V1) +{ VT12 VLEX12 CLSR12 +TTL: + {object V2; /* PNAME */ + V2= symbol_name((V1)); + {int V3; /* LEN */ + V3= ((V2))->v.v_fillp; + L4(1,MAKE_FIXNUM(10)) /* PACK-TYPE-TAG */; + {int V4; /* INFO */ + V4= (((V3 = pvm_pkint(&type,1,1)) == PvmOk) ? + pvm_pkstr(((V2))->st.st_self) : V3); + if((0)==(V4)){ + goto L61;} + L1(2,MAKE_FIXNUM(V4),VV[23]) /* PVM-ERROR */; + } + } + } +L61: + RETURN(0); +} +/* function definition for C-OBUFFER-STRING */ +static L16(int narg, object V1) +{ VT13 VLEX13 CLSR13 +TTL: + {int V2; /* LEN */ + V2= length((V1)); + L4(1,MAKE_FIXNUM(11)) /* PACK-TYPE-TAG */; + {int V3; /* INFO */ + V3= (((V2 = pvm_pkint(&type,1,1)) == PvmOk) ? + pvm_pkstr(((V1))->st.st_self) : V2); + if((0)==(V3)){ + goto L68;} + L1(2,MAKE_FIXNUM(V3),VV[24]) /* PVM-ERROR */; + } + } +L68: + RETURN(0); +} +/* function definition for C-OBUFFER-VECTOR-HEADER */ +static L17(int narg, object V1) +{ VT14 VLEX14 CLSR14 +TTL: + L4(1,MAKE_FIXNUM(12)) /* PACK-TYPE-TAG */; + {int V2; /* INFO */ + V2= pvm_pkint(&fix((V1)),1,1); + if((0)==(V2)){ + goto L75;} + L1(2,MAKE_FIXNUM(V2),VV[25]) /* PVM-ERROR */; + } +L75: + RETURN(0); +} +/* function definition for C-OBUFFER-LIST-HEADER */ +static L18(int narg) +{ VT15 VLEX15 CLSR15 +TTL: + L4(1,MAKE_FIXNUM(13)) /* PACK-TYPE-TAG */; + RETURN(0); +} +/* function definition for C_PVM_UNPACK_TAG */ +static L19(int narg) +{ + object x; + x= Cnil; + { int tagval, info; + info = pvm_upkint(&tagval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = MAKE_FIXNUM(tagval); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for IBUFFER-TAG */ +static L20(int narg) +{ VT16 VLEX16 CLSR16 +TTL: + { int V1; + object V2; /* INFO */ + object V3; /* VALUE */ + V1=L23(0) /* C_PVM_UNPACK_INT*/; + if (V1--==0) goto L81; + V2= VALUES(0); + if (V1--==0) goto L82; + V3= VALUES(1); + goto L83; +L81: + V2= Cnil; +L82: + V3= Cnil; +L83: + if(((V2))==Cnil){ + goto L85;} + VALUES(0) = (V3); + RETURN(1); +L85: + RETURN(L1(2,(V2),VV[26]) /* PVM-ERROR */);} +} +/* function definition for C-NEXT-MSG-TYPE */ +static L21(int narg) +{ VT17 VLEX17 CLSR17 +TTL: + RETURN(L20(0) /* IBUFFER-TAG */); +} +/* function definition for C_PVM_UNPACK_INT */ +static L23(int narg) +{ + object x; + x= Cnil; + { int ival, info; + info = pvm_upkint(&ival,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = MAKE_FIXNUM(ival); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for C-IBUFFER-INT */ +static L24(int narg) +{ VT18 VLEX18 CLSR18 +TTL: + { int V1; + object V2; /* INFO */ + object V3; /* VALUE */ + V1=L23(0) /* C_PVM_UNPACK_INT*/; + if (V1--==0) goto L88; + V2= VALUES(0); + if (V1--==0) goto L89; + V3= VALUES(1); + goto L90; +L88: + V2= Cnil; +L89: + V3= Cnil; +L90: + if(((V2))==Cnil){ + goto L92;} + VALUES(0) = (V3); + RETURN(1); +L92: + RETURN(L1(2,(V2),VV[27]) /* PVM-ERROR */);} +} +/* function definition for C_PVM_UNPACK_CHAR */ +static L25(int narg) +{ + object x; + x= Cnil; + { int info; + char chval; + info = pvm_upkbyte(&chval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = code_char(chval); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for C-IBUFFER-CHAR */ +static L26(int narg) +{ VT19 VLEX19 CLSR19 +TTL: + { int V1; + object V2; /* INFO */ + object V3; /* VALUE */ + V1=L25(0) /* C_PVM_UNPACK_CHAR*/; + if (V1--==0) goto L95; + V2= VALUES(0); + if (V1--==0) goto L96; + V3= VALUES(1); + goto L97; +L95: + V2= Cnil; +L96: + V3= Cnil; +L97: + if(((V2))==Cnil){ + goto L99;} + VALUES(0) = (V3); + RETURN(1); +L99: + RETURN(L1(2,(V2),VV[28]) /* PVM-ERROR */);} +} +/* function definition for C_PVM_UNPACK_FLOAT */ +static L27(int narg) +{ + object x; + x= Cnil; + { int info; + float fval; + info = pvm_upkfloat(&fval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_shortfloat(fval); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for IBUFFER-FLOAT */ +static L28(int narg) +{ VT20 VLEX20 CLSR20 +TTL: + { int V1; + object V2; /* INFO */ + object V3; /* VALUE */ + V1=L27(0) /* C_PVM_UNPACK_FLOAT*/; + if (V1--==0) goto L102; + V2= VALUES(0); + if (V1--==0) goto L103; + V3= VALUES(1); + goto L104; +L102: + V2= Cnil; +L103: + V3= Cnil; +L104: + if(((V2))==Cnil){ + goto L106;} + VALUES(0) = (V3); + RETURN(1); +L106: + RETURN(L1(2,(V2),VV[29]) /* PVM-ERROR */);} +} +/* function definition for C_PVM_UNPACK_DOUBLE */ +static L29(int narg) +{ + object x; + x= Cnil; + { + int info; + double dval; + info = pvm_upkdouble(&dval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_longfloat(dval); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for C-IBUFFER-DOUBLE */ +static L30(int narg) +{ VT21 VLEX21 CLSR21 +TTL: + { int V1; + object V2; /* INFO */ + object V3; /* VALUE */ + V1=L29(0) /* C_PVM_UNPACK_DOUBLE*/; + if (V1--==0) goto L109; + V2= VALUES(0); + if (V1--==0) goto L110; + V3= VALUES(1); + goto L111; +L109: + V2= Cnil; +L110: + V3= Cnil; +L111: + if(((V2))==Cnil){ + goto L113;} + VALUES(0) = (V3); + RETURN(1); +L113: + RETURN(L1(2,(V2),VV[30]) /* PVM-ERROR */);} +} +/* function definition for SETSTRING */ +static L31(int narg, object V1, object V2, object V3) +{ VT22 VLEX22 CLSR22 +TTL: + aset1((V3),fix((V2)),(V1)); + RETURN(0); +} +/* function definition for C_PVM_UNPACK_CHARS */ +static L32(int narg, object V1) +{ + object x; + x= + Cnil; + { char *strchrs; + int info; + info = pvm_upkstr(strchrs); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_simple_string(strchrs); + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for GET-LENGTH-AND-STRING */ +static L33(int narg) +{ VT23 VLEX23 CLSR23 +TTL: + {object V1; /* LEN */ + (*LK0)(0) /* IBUFFER-INT */; + V1= VALUES(0); + { int V2; + object V3; /* INFO */ + object V4; /* STR */ + V2=L32(1,(V1)) /* C_PVM_UNPACK_CHARS*/; + if (V2--==0) goto L118; + V3= VALUES(0); + if (V2--==0) goto L119; + V4= VALUES(1); + goto L120; +L118: + V3= Cnil; +L119: + V4= Cnil; +L120: + if(((V3))==Cnil){ + goto L122;} + if(!(number_compare(MAKE_FIXNUM(length((V4))),(V1))==0)){ + goto L125;} + VALUES(0) = (V4); + RETURN(1); +L125: + RETURN(Lformat(4,Ct,VV[31],MAKE_FIXNUM(length((V4))),(V1))/* FORMAT*/); +L122: + RETURN(L1(2,(V3),VV[32]) /* PVM-ERROR */);} + } +} +/* function definition for C-IBUFFER-SYMBOL */ +static L34(int narg) +{ VT24 VLEX24 CLSR24 +TTL: + {object V1; /* PNAME */ + L33(0) /* GET-LENGTH-AND-STRING*/; + V1= VALUES(0); + RETURN(Lmake_symbol(1,(V1)) /* MAKE-SYMBOL */); + } +} +/* function definition for C-IBUFFER-STRING */ +static L35(int narg) +{ VT25 VLEX25 CLSR25 +TTL: + RETURN(L33(0) /* GET-LENGTH-AND-STRING*/); +} +/* function definition for C-IBUFER-VECTOR-LENGTH */ +static L36(int narg) +{ VT26 VLEX26 CLSR26 +TTL: + RETURN(L24(0) /* C-IBUFFER-INT */); +} +/* function definition for C_PVM_INITSEND */ +static L37(int narg, object V1) +{ + int x; + x=pvm_initsend(object_to_int(V1)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-INIT-SEND */ +static L38(int narg, object V1) +{ VT27 VLEX27 CLSR27 +TTL: + if(type_of((V1))==t_fixnum||type_of((V1))==t_bignum){ + goto L129;} + RETURN(Lerror(2,VV[36],TYPE_OF((V1))) /* ERROR */); +L129: + if(!(number_compare(MAKE_FIXNUM(0),(V1))>0)){ + goto L132;} + RETURN(Lerror(2,VV[37],(V1)) /* ERROR */); +L132: + {register int V2; /* BUFID */ + V2= pvm_initsend(fix((V1))); + if(!((V2)<0)){ + goto L135;} + L1(2,MAKE_FIXNUM(V2),VV[38]) /* PVM-ERROR */; +L135: + VALUES(0) = MAKE_FIXNUM(V2); + RETURN(1); + } +} +/* function definition for C_PVM_SEND */ +static L39(int narg, object V1, object V2) +{ + int x; + x=pvm_send(object_to_int(V1), object_to_int(V2)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-SEND-MESSAGE */ +static L40(int narg, object V1, object V2, object V3, object V4, ...) +{ VT28 VLEX28 CLSR28 + {int i=4; + object V5; + va_list args; va_start(args, V4); + if (i==narg) goto L138; + V5= va_arg(args, object); + i++; + goto L139; +L138: + V5= MAKE_FIXNUM(0); +L139: + L38(1,(V5)) /* LPVM-INIT-SEND */; + (*LK1)(2,(V1),(V2)) /* WRITE-OBJECT */; + {int V6; /* INFO */ + V6= pvm_send(fix((V4)), fix((V3))); + if(!((V6)<0)){ + goto L143;} + L1(2,MAKE_FIXNUM(V6),VV[42]) /* PVM-ERROR */; + } +L143: + RETURN(0); + } +} +/* function definition for LPVM-MULTICAST */ +static L41(int narg, object V1, object V2, object V3, object V4, ...) +{ VT29 VLEX29 CLSR29 + {int i=4; + volatile object V5; + va_list args; va_start(args, V4); + if (i==narg) goto L147; + V5= va_arg(args, object); + i++; + goto L148; +L147: + V5= MAKE_FIXNUM(0); +L148: + L38(1,(V5)) /* LPVM-INIT-SEND */; + (*LK1)(2,(V1),(V2)) /* WRITE-OBJECT */; + {volatile object V6; + volatile object V7; /* TID */ + V6= (V4); + V7= Cnil; +L156: + if(!((V6)==Cnil)){ + goto L157;} + goto L152; +L157: + V7= CAR((V6)); + {register int V9; /* INFO */ + V9= pvm_send(fix((V7)), fix((V3))); + if(!((V9)<0)){ + goto L162;} + L1(2,MAKE_FIXNUM(V9),VV[43]) /* PVM-ERROR */; + } +L162: + V6= CDR((V6)); + goto L156; + } +L152: + RETURN(0); + } +} +/* function definition for C_PVM_NRECV */ +static L42(int narg, object V1, object V2) +{ + int x; + x=pvm_nrecv(object_to_int(V1),object_to_int(V2)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-NONBLOCKING-RECV */ +static L43(int narg, object V1, object V2, object V3) +{ VT30 VLEX30 CLSR30 +TTL: + {register int V4; /* BUFID */ + V4= pvm_nrecv(fix((V2)),fix((V3))); + if(!((V4)<0)){ + goto L171;} + RETURN(L1(2,MAKE_FIXNUM(V4),VV[47]) /* PVM-ERROR */); +L171: + if(!((0)==(V4))){ + goto L174;} + VALUES(0) = Cnil; + RETURN(1); +L174: + if(!((V4)>0)){ + goto L177;} + RETURN((*LK2)(1,(V1)) /* READ-OBJECT */); +L177: + RETURN(Lerror(1,VV[48]) /* ERROR */); + } +} +/* function definition for C_PVM_RECV */ +static L44(int narg, object V1, object V2) +{ + int x; + x=pvm_recv(object_to_int(V1), object_to_int(V2)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-BLOCKING-READ */ +static L45(int narg, object V1, object V2, object V3) +{ VT31 VLEX31 CLSR31 +TTL: + {int V4; /* BUFID */ + V4= pvm_recv(fix((V2)), fix((V3))); + if(!((V4)<0)){ + goto L180;} + L1(2,MAKE_FIXNUM(V4),VV[52]) /* PVM-ERROR */; +L180: + RETURN((*LK2)(1,(V1)) /* READ-OBJECT */); + } +} +/* function definition for C_PVM_MYTID */ +static L46(int narg) +{ + int x; + x=pvm_mytid(); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-MY-TID */ +static L47(int narg) +{ VT32 VLEX32 CLSR32 +TTL: + {register int V1; /* INFO */ + V1= pvm_mytid(); + if(!((V1)<0)){ + goto L184;} + L1(2,MAKE_FIXNUM(V1),VV[56]) /* PVM-ERROR */; +L184: + VALUES(0) = MAKE_FIXNUM(V1); + RETURN(1); + } +} +/* function definition for C_PVM_EXIT */ +static L48(int narg) +{ + int x; + x=pvm_exit(); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-EXIT */ +static L49(int narg) +{ VT33 VLEX33 CLSR33 +TTL: + {int V1; /* INFO */ + V1= pvm_exit(); + if((0)==(V1)){ + goto L187;} + L1(2,MAKE_FIXNUM(V1),VV[60]) /* PVM-ERROR */; + } +L187: + RETURN(0); +} +/* function definition for C_PVM_KILL */ +static L50(int narg, object V1) +{ + int x; + x=pvm_kill(object_to_int(V1)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-KILL */ +static L51(int narg, object V1) +{ VT34 VLEX34 CLSR34 +TTL: + {int V2; /* INFO */ + V2= pvm_kill(fix((V1))); + if(!((V2)<0)){ + goto L191;} + L1(2,MAKE_FIXNUM(V2),VV[64]) /* PVM-ERROR */; + } +L191: + RETURN(0); +} +/* function definition for C_PVM_PARENT */ +static L52(int narg) +{ + int x; + x=pvm_parent(); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-PARENT */ +static L53(int narg) +{ VT35 VLEX35 CLSR35 +TTL: + {int V1; /* INFO */ + V1= pvm_parent(); + if(!((V1)==(-23))){ + goto L195;} + L1(2,MAKE_FIXNUM(V1),VV[68]) /* PVM-ERROR */; + } +L195: + RETURN(0); +} +/* function definition for C_PVM_PSTAT */ +static L54(int narg, object V1) +{ + int x; + x=pvm_pstat(object_to_int(V1)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-PSTAT */ +static L55(int narg, object V1) +{ VT36 VLEX36 CLSR36 +TTL: + {register int V2; /* INFO */ + V2= pvm_pstat(fix((V1))); + if(!((V2)==(0))){ + goto L201;} + VALUES(0) = MAKE_FIXNUM(V2); + RETURN(1); +L201: + if(!((V2)==(-31))){ + goto L204;} + VALUES(0) = MAKE_FIXNUM(V2); + RETURN(1); +L204: + RETURN(L1(2,MAKE_FIXNUM(V2),VV[72]) /* PVM-ERROR */); + } +} +/* function definition for C_PVM_MSTAT */ +static L56(int narg, object V1) +{ + int x; + x=pvm_mstat(V1->st.st_self); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-MSTAT */ +static L57(int narg, object V1) +{ VT37 VLEX37 CLSR37 +TTL: + if(type_of((V1))==t_string){ + goto L206;} + Lerror(2,VV[76],TYPE_OF((V1))) /* ERROR */; +L206: + {register int V2; /* INFO */ + V2= pvm_mstat((V1)->st.st_self); + if(!((V2)==(0))){ + goto L211;} + VALUES(0) = VV[77]; + RETURN(1); +L211: + if(!((V2)==(-6))){ + goto L214;} + VALUES(0) = VV[78]; + RETURN(1); +L214: + if(!((V2)==(-22))){ + goto L217;} + VALUES(0) = VV[79]; + RETURN(1); +L217: + RETURN(L1(2,MAKE_FIXNUM(V2),VV[80]) /* PVM-ERROR */); + } +} +/* function definition for C_PVM_SPAWN */ +static L58(int narg, object V1, object V2, object V3, object V4) +{ + object x; + x= + Cnil; + { + int numt, tid, i; + int sz = object_to_int(V2); + object v; + extern object lisp_package; + + siLmake_vector(7, intern("FIXNUM", lisp_package), + MAKE_FIXNUM(sz), Cnil, Cnil, Cnil, Cnil, Cnil); + v = VALUES(0); + numt = pvm_spawn(V1->st.st_self, 0, object_to_int(V2), V3->st.st_self, object_to_int(V4), v->v_self); + if (numt < PvmOk) RETURN(1); + VALUES(0) = MAKE_FIXNUM(numt); + VALUES(1) = v; + RETURN(2); + }; + VALUES(0)=x; + RETURN(1); +} +/* function definition for LPVM-SPAWN */ +static L59(int narg, object V1, object V2, object V3, object V4) +{ VT38 VLEX38 CLSR38 +TTL: + if(type_of((V1))==t_string){ + goto L220;} + RETURN(Lerror(2,VV[81],TYPE_OF((V1))) /* ERROR */); +L220: + if(type_of((V2))==t_fixnum||type_of((V2))==t_bignum){ + goto L223;} + RETURN(Lerror(2,VV[82],TYPE_OF((V2))) /* ERROR */); +L223: + if(type_of((V3))==t_string){ + goto L226;} + RETURN(Lerror(2,VV[83],TYPE_OF((V3))) /* ERROR */); +L226: + if(type_of((V4))==t_fixnum||type_of((V4))==t_bignum){ + goto L229;} + RETURN(Lerror(2,VV[84],TYPE_OF((V4))) /* ERROR */); +L229: + if(!(number_compare(MAKE_FIXNUM(1),(V4))<=0)){ + goto L231;} + if(number_compare((V4),MAKE_FIXNUM(32))<=0){ + goto L232;} +L231: + RETURN(Lerror(2,VV[85],(V4)) /* ERROR */); +L232: + { int V5; + object V6; /* NUM-SPAWNED */ + object V7; /* TIDS */ + V5=L58(4,(V1),(V2),(V3),(V4)) /* C_PVM_SPAWN */; + if (V5--==0) goto L237; + V6= VALUES(0); + if (V5--==0) goto L238; + V7= VALUES(1); + goto L239; +L237: + V6= Cnil; +L238: + V7= Cnil; +L239: + if(!(number_compare(MAKE_FIXNUM(0),(V6))>0)){ + goto L241;} + RETURN(L1(2,(V6),VV[86]) /* PVM-ERROR */); +L241: + VALUES(1) = (V7); + VALUES(0) = (V6); + RETURN(2);} +} +/* function definition for C_PVM_SENDSIG */ +static L60(int narg, object V1, object V2) +{ + int x; + x=pvm_sendsig(object_to_int(V1),object_to_int(V2)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-SENDSIG */ +static L61(int narg, object V1, object V2) +{ VT39 VLEX39 CLSR39 +TTL: + {int V3; /* INFO */ + V3= pvm_sendsig(fix((V1)),fix((V2))); + if(!((V3)<0)){ + goto L243;} + L1(2,MAKE_FIXNUM(V3),VV[90]) /* PVM-ERROR */; + } +L243: + RETURN(0); +} +/* function definition for C_PVM_ADVISE */ +static L62(int narg, object V1) +{ + int x; + x=pvm_advise(object_to_int(V1)); + VALUES(0)=MAKE_FIXNUM(x); + RETURN(1); +} +/* function definition for LPVM-ADVISE */ +static L63(int narg, object V1) +{ VT40 VLEX40 CLSR40 +TTL: + {int V2; /* INFO */ + V2= pvm_advise(fix((V1))); + if((V2)==(0)){ + goto L247;} + L1(2,MAKE_FIXNUM(V2),VV[94]) /* PVM-ERROR */; + } +L247: + RETURN(0); +} +static LKF2(int narg, ...) {TRAMPOLINK(VV[160],&LK2);} +static LKF1(int narg, ...) {TRAMPOLINK(VV[157],&LK1);} +static LKF0(int narg, ...) {TRAMPOLINK(VV[155],&LK0);} diff --git a/contrib/pvm/pvmecl.lsp b/contrib/pvm/pvmecl.lsp new file mode 100644 index 000000000..372739fcd --- /dev/null +++ b/contrib/pvm/pvmecl.lsp @@ -0,0 +1,756 @@ +;;;-*-Mode:LISP; Syntax: Common LISP; Base: 10-*- +;;; +;;; File = pvmecl.lsp +;;; Interface between ECoLISP and PVM. +;;; This file contains the C function interface between ECoLisp and PVM. +;;; It is not portable. +;;; +;;; +;;; (c) 1994, I.D. Alexander-Craig, all rights reserved. +;;; +;;; + +;;; +;;; pvmconsts.lsp must be loaded before this file. +;;; + +;;; +;;; Error function for PVM interface. +;;; + +(defun pvm-error (errno routine) + (error "PVM interface error ~d in ~a~%" errno routine)) + + +(clines " +#include \"/project/pvm/pvm3/include/pvm3.h\" +") + + +;;; +;;; Begin with buffering routines. +;;; + +;; +;; Start with output buffering routines for simple types. +;; Each C function is followed by the corresponding entry +;; definition. Then comes the LISP function. +;; + + +(definline c_pvm_pkint (fixnum) fixnum + "({int x = #0; pvm_pkint(&x,1,1);})" +) + +(defun obuffer-int (i) + (let ((info (c_pvm_pkint i))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-int"))) + (values)) + +;; +;; Packing routine for message types. This is a LISP function +;; that calls c_pvm_pkint to pack the type. +;; + +(defun pack-type-tag (typetag) + (let ((return-code (c_pvm_pkint typetag))) + (unless (= %PvmOk return-code) + (pvm-error return-code "pack-type-tag"))) + (values)) + +(defun C-obuffer-nil () + (pack-type-tag LISP_NIL_TYPE)) + +(defun C-obuffer-t () + (pack-type-tag LISP_T_TYPE)) + +(definline c_pvm_pkchar (character) fixnum + "({char x = #0; pvm_pkbyte(&x,1,1);})" +) + +(defun C-obuffer-char (ch) + (pack-type-tag LISP_CHAR_TYPE) + (let ((info (c_pvm_pkchar ch))) + (unless (= %PvmOk info) + (pvm-error info "pvm_pkchar call"))) + (values)) + +(defun C-obuffer-int (i) + (pack-type-tag LISP_INT_TYPE) + (let ((info (c_pvm_pkint i))) + (unless (= %PvmOk info) + (pvm-error info "pvm_pkint call"))) + (values)) + +(definline c_pvm_pkfloat (short-float) fixnum + "({float x = #0; pvm_pkfloat(&x,1,1);})" +) + +(defun obuffer-float (fl) + (let ((info (c_pvm_pkfloat fl))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-float"))) + (values)) + +(definline c_pvm_pkdouble (long-float) fixnum + "({double x = #0; pvm_pkdouble(&x,1,1);})" +) + +(defun C-obuffer-double (db) + (let ((info (c_pvm_pkdouble db))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-double"))) + (values)) + +;; +;; Packing routines for symbol and string. +;; Both routines expect a string and a number (in that order) +;; to be supplied to them. +;; The number is the length of the string. +;; +;; +;; The first function packs the length and the string into +;; the output buffer. +;; +(definline c_pvm_pkstr (string fixnum) fixnum + "({int type = #1; + type = pvm_pkint(&type,1,1); + ((type == PvmOk) ? pvm_pkstr((#0)->st.st_self) : type);})" +) +;; +;; Now define the routines that manipulate symbols and strings. +;; + +(defun C-obuffer-symbol (s) + (let ((pname (symbol-name s))) + (let ((len (length pname))) + (pack-type-tag LISP_SYMBOL_TYPE) + (let ((info (c_pvm_pkstr pname len))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-symbol"))))) + (values)) + +(defun C-obuffer-string (str) + (let ((len (length str))) + (pack-type-tag LISP_STRING_TYPE) + (let ((info (c_pvm_pkstr str len))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-string")))) + (values)) + +;; +;; Packing routines for vector and list headers. +;; + +(defun C-obuffer-vector-header (vector-length) + (pack-type-tag LISP_VECTOR_TYPE) + (let ((info (c_pvm_pkint vector-length))) + (unless (= %PvmOk info) + (pvm-error info "obuffer-vector-header"))) + (values)) + +(defun C-obuffer-list-header () + (pack-type-tag LISP_LIST_TYPE) + (values)) + +;; +;; Unpacking routines for scalar types. +;; + +(defcbody c_pvm_unpack_tag () object +" Cnil; + { int tagval, info; + info = pvm_upkint(&tagval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = MAKE_FIXNUM(tagval); + RETURN(2); + }" +) + +;(proclaim '(inline ibuffer-tag)) +(defun ibuffer-tag () + (multiple-value-bind (info value) + (c_pvm_unpack_int) + (if info + value + (pvm-error info "ibuffer-tag")))) + +(defun C-next-msg-type () + (ibuffer-tag)) + +(defun C-next-type-name () + (ibuffer-tag)) + +(defcbody c_pvm_unpack_int () object +" Cnil; + { int ival, info; + info = pvm_upkint(&ival,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = MAKE_FIXNUM(ival); + RETURN(2); + }" +) + +(defun C-ibuffer-int () + (multiple-value-bind (info value) + (c_pvm_unpack_int) + (if info + value + (pvm-error info "ibuffer-int")))) + +(defcbody c_pvm_unpack_char () object +" Cnil; + { int info; + char chval; + info = pvm_upkbyte(&chval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = code_char(chval); + RETURN(2); + }" +) + +(defun C-ibuffer-char () + (multiple-value-bind (info value) + (c_pvm_unpack_char) + (if info + value + (pvm-error info "ibuffer-char")))) + +(defcbody c_pvm_unpack_float () object +" Cnil; + { int info; + float fval; + info = pvm_upkfloat(&fval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_shortfloat(fval); + RETURN(2); + }" +) + +(defun ibuffer-float () + (multiple-value-bind (info value) + (c_pvm_unpack_float) + (if info + value + (pvm-error info "ibuffer-float")))) + +(defcbody c_pvm_unpack_double () object +" Cnil; + { + int info; + double dval; + info = pvm_upkdouble(&dval,1,1); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_longfloat(dval); + RETURN(2); + }" +) + +(defun C-ibuffer-double () + (multiple-value-bind (info value) + (c_pvm_unpack_double) + (if info + value + (pvm-error info "ibuffer-double")))) + + +;; +;; Routines to get symbols and strings from the PVM +;; buffer. +;; This is a little tricky! +;; + +;; +;; First, a general unpacking routine for strings. +;; + +(defun setstring (chr indx str) + (setf (aref str indx) chr) + (values)) + +(defcbody c_pvm_unpack_chars (fixnum) object +" + Cnil; + { char *strchrs; + int info; + info = pvm_upkstr(strchrs); + if (info != PvmOk) { VALUES(0) = Cnil; RETURN(1);} + VALUES(0) = MAKE_FIXNUM(info); + VALUES(1) = make_simple_string(strchrs); + RETURN(2); + }" +) + + +;; +;; Now the routine which gets the length and the string +;; from the buffer. +;; + +(defun get-length-and-string () + (let ((len (ibuffer-int))) + (multiple-value-bind (info str) + (c_pvm_unpack_chars len) + (if info + (if (= (length str) len) + str + (format + t + "received string has length ~a, not ~a as promised.~%" + (length str) + len)) + (pvm-error info "get-length-and-string"))))) + +(defun C-ibuffer-symbol () + ; It might be useful sometimes just to return the string. + (let ((pname (get-length-and-string))) + (make-symbol pname))) + +(defun C-ibuffer-string () + (get-length-and-string)) + + +(defun C-ibufer-vector-length () + (C-ibuffer-int)) + + +;;; +;;; Send and received routines (together with registration and exit). +;;; + +(definline c_pvm_initsend (fixnum) fixnum + "pvm_initsend(#0)") + +(defun lpvm-init-send (encoding) + (cond ((not (integerp encoding)) + (error "lpvm-init-send expects an int, not a ~a~%" + (type-of encoding))) + ((minusp encoding) + (error + "lpvm-init-send: encoding must be non-negative (~d)~%" + encoding)) + (t + (let ((bufid (c_pvm_initsend encoding))) + (when (minusp bufid) + (pvm-error bufid "pvm_initsend call")) + bufid)))) + +(definline c_pvm_send (fixnum fixnum) fixnum + "pvm_send(#0, #1)") + +;;; +;;; The send routine. +;;; + +(defun lpvm-send-message (lisp-object + reader-object + message-type + destination-task + &optional (encoding %PvmDataDefault)) + (lpvm-init-send encoding) + (write-object lisp-object reader-object) + (let ((info (c_pvm_send destination-task message-type))) + (when (minusp info) + (pvm-error info "pvm_send call"))) + (values)) + +;;; +;;; The multi-cast routine is similar, but we set up the buffer +;;; once and then repeatedly send the message. +;;; + +(defun lpvm-multicast (lisp-object + reader-object + message-type + destination-tasks + &optional (encoding %PvmDataDefault)) + (lpvm-init-send encoding) + (write-object lisp-object reader-object) + (dolist (tid destination-tasks) + (let ((info (c_pvm_send tid message-type))) + (when (minusp info) + (pvm-error info "pvm_multicast")))) + (values)) + +;;; +;;; Receive routines. +;;; + +(definline c_pvm_nrecv (fixnum fixnum) fixnum + "pvm_nrecv(#0,#1)" +) + +(defun lpvm-nonblocking-recv (object-reader tid msgtag) + (let ((bufid (c_pvm_nrecv tid msgtag))) + (cond ((minusp bufid) + (pvm-error bufid "pvm_nrecv")) + ((= %PvmOk bufid) + ()) ; nothing there + ((plusp bufid) + (read-object object-reader)) + (t + (error + "something weird has happened---nonblocking-recv"))))) + +(definline c_pvm_recv (fixnum fixnum) fixnum + "pvm_recv(#0, #1)" +) + +(defun lpvm-blocking-read (object-reader tid msgtag) + (let ((bufid (c_pvm_recv tid msgtag))) + (when (minusp bufid) + (pvm-error bufid "pvm_recv")) + (read-object object-reader))) + + +;;; +;;; Join PVM primitive. +;;; + +(definline c_pvm_mytid () fixnum + "pvm_mytid()" +) + +(defun lpvm-my-tid () + (let ((info (c_pvm_mytid))) + (when (minusp info) + (pvm-error info "pvm_mytid call")) + info)) + + +;;; +;;; Leave PVM primitive. +;;; + +(definline c_pvm_exit () fixnum + "pvm_exit()") + +(defun lpvm-exit () + (let ((info (c_pvm_exit))) + (unless (= %PvmOk info) + (pvm-error info "pvm_exit call"))) + (values)) + + +(definline c_pvm_kill (fixnum) fixnum + "pvm_kill(#0)" +) + +(defun lpvm-kill (tid) + (let ((info (c_pvm_kill tid))) + (when (minusp info) + (pvm-error info "pvm_kill call"))) + (values)) + +(definline c_pvm_parent () fixnum + "pvm_parent()" +) + +(defun lpvm-parent () + (let ((info (c_pvm_parent))) + (when (= info %PvmNoParent) + (pvm-error info "pvm_parent"))) + (values)) + +(definline c_pvm_pstat (fixnum) fixnum + "pvm_pstat(#0)" +) + +(defun lpvm-pstat (tid) + (let ((info (c_pvm_pstat tid))) + (cond ((= info %PvmOk) + info) + ((= info %PvmNoTask) + info) + (t + (pvm-error info "pvm_stat call"))))) + +(definline c_pvm_mstat (string) fixnum + "pvm_mstat(#0->st.st_self)" +) + +(defun lpvm-mstat (hostname) + (unless (stringp hostname) + (error "lpvm-mstat: hostnames must be strings, not ~a~%" + (type-of hostname))) + (let ((info (c_pvm_mstat hostname))) + (cond ((= info %PvmOk) + 'running) + ((= info %PvmNoHost) + 'no-such-host) + ((= info %PvmHostFail) + 'host-unreachable) + (t + (pvm-error info "pvm_mstat call"))))) + +(defcbody c_pvm_spawn (string fixnum string fixnum) object +" + Cnil; + { + int numt, tid, i; + int sz = #1; + object v; + extern object lisp_package; + + siLmake_vector(7, intern(\"FIXNUM\", lisp_package), + MAKE_FIXNUM(sz), Cnil, Cnil, Cnil, Cnil, Cnil); + v = VALUES(0); + numt = pvm_spawn(#0->st.st_self, 0, #1, #2->st.st_self, #3, v->v.v_self); + if (numt < PvmOk) RETURN(1); + VALUES(0) = MAKE_FIXNUM(numt); + VALUES(1) = v; + RETURN(2); + }" +) + +(defun lpvm-spawn (taskname flag where numtasks) + (cond ((not (stringp taskname)) + (error "spawn -- wrong type: ~A" (type-of taskname))) + ((not (integerp flag)) + (error "spawn -- wrong type: ~A" (type-of flag))) + ((not (stringp where)) + (error "spawn -- wrong type: ~A" (type-of where))) + ((not (integerp numtasks)) + (error "spawn -- wrong type: ~A" (type-of numtasks))) + ((not (and (<= 1 numtasks) + (<= numtasks 32))) + (error "spawn -- wrong number of tasks: ~D" numtasks)) + (t + (multiple-value-bind (num-spawned tids) + (c_pvm_spawn taskname flag where numtasks) + (if (minusp num-spawned) + (pvm-error num-spawned "pvm_spawn call") + (values num-spawned tids)))))) + + +(definline c_pvm_sendsig (fixnum fixnum) fixnum + "pvm_sendsig(#0,#1)" +) + +(defun lpvm-sendsig (tid signum) + (let ((info (c_pvm_sendsig tid signum))) + (when (minusp info) + (pvm-error info "pvm_sendsig call"))) + (values)) + +(definline c_pvm_advise (fixnum) fixnum + "pvm_advise(#0)" +) + +(defun lpvm-advise (route) + (let ((info (c_pvm_advise route))) + (unless (= info %PvmOk) + (pvm-error info "pvm_advise call"))) + (values)) + +;;;; +;;;; Group operations. +;;;; + + +(definline c_pvm_join_group (object) fixnum + "pvm_joingroup(#0->st.st_self)" +) + +(defun lpvm-join-group (group) + (unless (stringp group) + (error "lpvm-join-grou expects a string, not a ~a~%" + (type-of group))) + (let ((inum (c_pvm_joingroup group))) + (when (minusp inum) + (pvm-error inum "pvm_joingroup call")) + inum)) + +(definline c_pvm_leave_group (object) fixnum + "pvm_lvgroup(#0->st.st_self)" +) + +(defun lpvm-leave-group (group) + (unless (stringp group) + (error + "lpvm-leave-group expects a string, not a ~a~%" + (type-of group))) + (let ((info (c_pvm_leave_group group))) + (when (minusp info) + (pvm-error info "pvm_lvgroup call"))) + (values)) + +(definline c_pvm_get_tid (object fixnum) fixnum + "pvm_gettid(#0->st.st_self, #1)" +) + +(defun lpvm-get-tid (group inum) + (unless (stringp group) + (error + "lpvm-get-tid expects arg 1 to be a string, not a ~a~%" + (type-of group))) + (unless (integerp inum) + (error + "lpvm-get-tid expects arg 2 to be an int, not a ~a~%" + (type-of inum))) + (let ((info (c_pvm_get_tid group inum))) + (cond ((plusp info) + info) + ((minusp info) + (pvm-error info "pvm_gettid call")) + (t + (pvm-error 0 "pvm_gettid: should not happen"))))) + +(definline c_pvm_get_inst (object fixnum) fixnum + "pvm_getinst(#0->st.st_self, #1)" +) + +(defun lpvm-get-inst-no (group tid) + (cond ((not (stringp group)) + (error + "lpvm-get-inst-no expects arg1 to be a string, not a ~a~%" + (type-of group))) + ((not (integerp tid)) + (error + "lpvm-get-inst-no expects arg2 to be an int, not a ~a~%" + (type-of tid))) + (t + (let ((inum (c_pvm_get_inst group tid))) + (when (minusp inum) + (pvm-error inum "pvm_getinst call")) + inum)))) + +(definline c_pvm_grpsize (object) fixnum + "pvm_gsize(#0->st.st_self)" +) + +(defun lpvm-group-size (group) + (unless (stringp group) + (error + "lpvm-group-size expects a string not a ~a~%" + (type-of group))) + (let ((size (c_pvm_grpsize group))) + (when (minusp size) + (pvm-error size "pvm_gsize call")) + size)) + +(definline c_pvm_barrier (object fixnum) fixnum + "pvm_barrier(#0->st.st_self,#1)" +) + +(defun lpvm-barrier (group count) + (cond ((not (stringp group)) + (error + "lpvm-barrier expects arg 1 to be a string, not a ~a~%" + (type-of group))) + ((not (integerp count)) + (error + "lpvm-barriet expects arg 2 to be an int, not a ~a~%" + (type-of count))) + (t + (let ((info (c_pvm_barrier group count))) + (unless (= %PvmOk info) + (pvm-error info "pvm_barrier call"))))) + (values)) + +(definline c_pvm_broadcast (object fixnum) fixnum + "pvm_bcast(#0->st.st_self,#1)" +) + +(defun lpvm-broadcast (lisp-object + reader-object + message-type + group-name + &optional (encoding %PvmDataDefault)) + (lpvm-init-send encoding) + (write-object lisp-object reader-object) + (let ((info (c_pvm_broadcast group-name message-type))) + (when (minusp info) + (pvm-error info "pvm_bcast call"))) + (values)) + + +(defCbody c_pvm_probe (fixnum fixnum) fixnum + "0; + { int bufid, info; + int *bytes; + int out_tid, out_tag; + VALUES(0) = Cnil; + bufid = pvm_probe(#0,#1); + if (bufid == 0) RETURN(1); + if (bufid < 0) { + VALUES(0) = CONS(MAKE_FIXNUM(bufid), Cnil); + RETURN(1); + } + info = pvm_bufinfo(bufid,bytes,&out_tag,&out_tid); + VALUES(0) = list(3, MAKE_FIXNUM(info), MAKE_FIXNUM(out_tag), + MAKE_FIXNUM(out_tid)); + RETURN(1); + }" +) + +(defun lpvm-probe (tid msgno) + (let ((return-val (c_pvm_probe tid msgno))) + (let ((num-returned (length return-val)) + (out-tid 0) + (out-tag 0) + (info 0)) + (cond ((= num-returned 1) + (pvm-error (car return-val) "pvm_probe call")) + (t + (setf info (first return-val)) + (setf out-tag (second return-val)) + (setf out-tid (third return-val)) + (if (= info %PvmOk) + (values out-tid out-tag) + (pvm-error info "pvm_probe call"))))))) + + +;;;; +;;;; Add and delete hosts. +;;;; + +;; +;; add_host adds a single host to the machine. hostname is the +;; string name of the host. The function returns a pair. + +(defCbody c_pvm_add_host (object) object + "Cnil; + { int host_info[1]; + int info, hival; + info = pvm_addhosts(&(#0)->st.st_self,1,host_info); + hival = host_info[0]; + VALUES(0) = list(2, MAKE_FIXNUM(info), MAKE_FIXNUM(hival)); + RETURN(1); + }" +) + +(defun add-hosts (hostnames) + (let ((results (make-array (length hostnames)))) + (dotimes (host (length hostnames)) + (let ((host (aref hostnames))) + (c_pvm_add_host host) + (setf (aref results host)(cadr host)))) + results)) + + +(defCbody c_pvm_del_host (object) object + "Cnil; + { int host_info[1]; + int info, hival; + info = pvm_delhosts(&(#0)->st.st_self,1,host_info); + hival = host_info[0]; + VALUES(0) = list(2, MAKE_FIXNUM(info), MAKE_FIXNUM(hival)); + RETURN(1); + }" +) + +(defun del-hosts (hostnames) + (let ((results (make-array (length hostnames)))) + (dotimes (host (length hostnames)) + (let ((host (aref hostnames))) + (c_pvm_add_host host) + (setf (aref results host) (cadr host)))) + results)) + diff --git a/contrib/pvm/pvmlisp.lsp b/contrib/pvm/pvmlisp.lsp new file mode 100644 index 000000000..67fb2e0b7 --- /dev/null +++ b/contrib/pvm/pvmlisp.lsp @@ -0,0 +1,620 @@ +;;;-*-Mode: LISP; Syntax: Common LISP; Base: 10-*- +;;; +;;; File = pvmlisp.lsp +;;; +;;; New version of reader structure using vectors. +;;; +;;; +;;; This code only works with Common LISP. It should not be included +;;; in a CLOS program (yet). It will also not work with CLiCC. +;;; +;;; +;;; Message-start-p is used to detect the start of a complex message. +;;; It is true if it is applied to a message tag. +;;; + +(defun message-start-p (mty) + (and (integerp mty) + (= MESSAGE_START mty))) + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; We define the reader object. This is a structure containing ;;;; +;;;; the function closures which perform the encoding and decoding. ;;;; +;;;; We begin by defining the encoder and decoder structures and ;;;; +;;;; manipulation functions (this will be a dream in CLOS or ;;;; +;;;; TELOS!) ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +;;; +;;; The encoder structure. +;;; The design of the encoder is such that it allows users to configure +;;; their own encoders. For example, CMU CL calls a SIMPLE-STRING a +;;; SIMPLE-BASE-STRING. This can be accomodated within this organisation +;;; at the cost of a little effort. +;;; +(defstruct encoder-rec + typename ;; value returned by type-of and used to index the + ;; encoder function + msgtypeno ;; the numeric message type + encoder-fn) + +;;; +;;; Encoders are held in hash tables. The following function (which +;;; should be inline) creates such a table. +;;; +;(declaim (inline make-encoder-structure)) +(proclaim '(inline make-encoder-structure)) + +(defun make-encoder-structure () + (make-hash-table :test #'eq)) + +;;; +;;; encoder-present-p is true if there is an encoder for the +;;; named type in the encoder table. +;;; + +(defun encoder-present-p (enc-struc typename) + (multiple-value-bind (encrec there) + (gethash typename enc-struc) + (declare (ignore encrec)) + there)) + +;;; +;;; Retrieval function for encoders. Given a type name, it returns the +;;; encoder function associated with the type. +;;; + +(defun get-encoder (enc-struc typename) + (multiple-value-bind (encoder-rec known-type) + (gethash typename enc-struc) + (if known-type + (encoder-rec-encoder-fn encoder-rec) + ()))) + +;;; +;;; Routine to store an encoder function. +;;; Assumes that typename and typeno have been checked. +;;; + +(defun put-encoder (enc-struc typename typeno encoder-fn) + (setf (gethash typename enc-struc) + (make-encoder-rec :encoder-fn encoder-fn + :typename typename + :msgtypeno typeno)) + (values)) + +;;;****************************************************************;;; +;;; ;;; +;;; ;;; +;;; A routine to replace the encoder function and a routine to ;;; +;;; remove an encode could be added here. ;;; +;;; ;;; +;;; ;;; +;;;****************************************************************;;; + +;;; +;;; message-type-number returns the type number associated with a +;;; symbolic type name. Its input is an encoder structure. +;;; + +(defun message-type-number (enc-struc typename) + (multiple-value-bind (enc-rec known-type) + (gethash typename enc-struc) + (if known-type + (encoder-rec-msgtypeno enc-rec) + (error "cannot return type number for type ~a: unknown type.~%" + typename)))) + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; The decoder structure and containing object. ;;;; +;;;; ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +;;; +;;; The decoder is indexed by its message type number. +;;; Decoders have a symbolic identifier associated with them. +;;; + +(defstruct decoder-rec + typename + decoder-fn) + +;;; +;;; Decoders are held in a hash table. The table is indexed by the +;;; message number. The hash table representation is used so that +;;; users can have gaps in their message number sequences. +;;; + +;(declaim (inline make-decoder-structure)) +(proclaim '(inline make-decoder-structure)) + +(defun make-decoder-structure () + (make-hash-table :test #'eql)) + +;;; +;;; decoder-present-p is true if there is a decoder structure +;;; in the decoder table at the point indexed by the numeric +;;; message type. +;;; + +(defun decoder-present-p (dec-struc msg-type-no) + (multiple-value-bind (decrec there) + (gethash msg-type-no dec-struc) + (declare (ignore decrec)) + there)) + +;;; +;;; get-decoder returns the decoder function associated with a +;;; message type number. If there is no such message, an error is raised. +;;; + +(defun get-decoder (decoder-struc msg-no) + (multiple-value-bind (decrec there) + (gethash msg-no decoder-struc) + (if there + (decoder-rec-decoder-fn decrec) + ()))) + +;;; +;;; put-decoder inserts a decoder record into the decoder vector. +;;; If a decoder structure is already in the vector at the place +;;; indexed by the message number, an error is raised. +;;; +;;; Note that this function will expand the vector if there is +;;; insufficient room. +;;; + +(defun put-decoder (decoder-struc msg-no msg-typename decoder-fn) + (setf (gethash msg-no decoder-struc) + (make-decoder-rec :typename msg-typename + :decoder-fn decoder-fn)) + (values)) + + +;;;****************************************************************;;; +;;; ;;; +;;; ;;; +;;; A routine to replace the decoder function and a routine to ;;; +;;; remove an encode could be added here. ;;; +;;; ;;; +;;; ;;; +;;;****************************************************************;;; + +;;; +;;; message-number-type returns the symbolic name associated with +;;; a numeric message type. +;;; + +(defun message-number-type (decoder-struc msg-type-no) + (decoder-rec-typename + (aref decoder-struc msg-type-no))) + + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; The reader object and its associated functions. ;;;; +;;;; Note that encoder and decoders can be added or removed at ;;;; +;;;; runtime. ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +(defstruct reader-object + (encoders (make-encoder-structure)) + (decoders (make-decoder-structure)) + (known-type-names ())) + +;;; +;;; A creation function for readers. +;;; + +(defun make-object-reader () + (make-reader-object)) + +;;; +;;; add-type-name adds a symbolic type name to the reader object. +;;; + +;(declaim (inline add-type-name)) +(proclaim '(inline add-type-name)) + +(defun add-type-name (reader-obj typename) + (pushnew typename + (reader-object-known-type-names reader-obj) + :test #'eq) + (values)) + +;;;; A deletion function can easily be defined. + +;;; +;;; valid-type-name-p is true iff the type name supplied as +;;; the second argument is known to the reader supplied as the +;;; first argument. +;;; + +;(declaim (inline valid-type-name-p)) +(proclaim '(inline valid-type-name-p)) + +(defun valid-type-namex-p (reader-obj typename) + (member typename + (reader-object-known-type-names reader-obj) + :test #'eq)) + +;(declaim (inline known-type-name-p)) +(proclaim '(inline known-type-name-p)) + +(defun known-type-name-p (reader-obj typename) + (member typename + (reader-object-known-type-names reader-obj) + :test #'eq)) + +;;; +;;; valid-message-type-no-p is true if the message type number +;;; supplied as the second argument is (i) positive and (ii) in the +;;; range 0 .. (length decoders) +;;; + +;(declaim (inline valid-message-type-no-p)) +(proclaim '(inline valid-message-type-no-p)) + +(defun valid-message-type-no-p (reader-obj msg-typeno) + (multiple-value-bind (decrec present) + (gethash msg-typeno + (reader-object-decoders reader-obj)) + (declare (ignore decrec)) + present)) + +;(declaim (inline known-type-number-p)) +(proclaim '(inline known-type-number-p)) + +(defun known-type-number-p (reader-obj msg-typeno) + (multiple-value-bind (decrec present) + (gethash msg-typeno + (reader-object-decoders reader-obj)) + (declare (ignore decrec)) + present)) + +;;; +;;; Routines to add encoder and decoder functions to a reader object. +;;; They can be called at runtime as well as at configuration time. +;;; Procedures to replace readers and writers could be defined if +;;; necessary---they won't be too difficult. +;;; + +(defun add-encoder (reader-obj ;; the reader object + message-type-no ;; the numeric type of the + ;; message type + message-type-name ;; the symbolic name of the + ;; message type + encoder-function) ;; the encoder function proper + ; start by checking that the type is not already known. + (when (and (known-type-name-p reader-obj message-type-name) + (encoder-present-p (reader-object-encoders reader-obj) + message-type-name)) + (error + "add-encoder: cannot add encoder for ~a -- one already present~%" + message-type-name)) + ; try to add the type name (a decoder might have put it there already) + (add-type-name reader-obj message-type-name) + ; add the encoder function + (put-encoder (reader-object-encoders reader-obj) + message-type-name + message-type-no + encoder-function) + (values)) + + +(defun add-decoder (reader-obj ;; the reader object + message-type-no ;; the numeric type of the + ;; message type + message-type-name ;; the symbolic name of the + ;; message type + decoder-function) ;; the encoder function proper + ; start by checking that the type is not already known + (when (and (known-type-name-p reader-obj message-type-name) + (decoder-present-p (reader-object-decoders reader-obj) + message-type-no)) + (error + "add-decoder: cannot add decoder for ~a -- one already present~%" + message-type-name)) + ; try to add the type name (an encoder might have already added it) + (add-type-name reader-obj message-type-name) + ; add the decoder function + (put-decoder (reader-object-decoders reader-obj) + message-type-no + message-type-name + decoder-function) + (values)) + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; Some utility functions. ;;;; +;;;; ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +;;; +;;; Only proper lists can be transmitted and received -- sorry. +;;; + +(defun proper-listp (l) + (and (not (null l)) + (list l) + (null (cdr (last l))))) + +;;; +;;; type-name is used in indexing the encoders. +;;; + +(defun type-name (typ) + (if (symbolp typ) + typ + (car typ))) + +;;; +;;; initialise-reader-object takes a reader object as its first +;;; argument and a list of lists of the following form: +;;; (typename -- a symbol +;;; typeno -- a natural number (one of the LISP_X_TYPEs) +;;; encoder -- a closure or the symbol '* +;;; decoder -- a closure or the symbol '* +;;; ) +;;; + +(defun initialise-reader-object (reader-obj ;; the reader to be started. + specs) ;; a list of reader and writer + ;; specifications + (dolist (spec specs) + (let ((typename (first spec)) + (typeno (second spec)) + (encfn (third spec)) + (decfn (fourth spec))) + (when (and (symbolp encfn) + (eq encfn '*) + (symbolp decfn) + (eq decfn '*)) + (error + "initialise reader: reader and writer for ~a both unspecified.~%" + typename)) + (unless (and (symbolp encfn) + (eq '* encfn)) + ; add an encoder. + (add-encoder reader-obj typeno typename encfn)) + (unless (and (symbolp decfn) + (eq '* decfn)) + (add-decoder reader-obj typeno typename decfn)))) + (values)) + + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; Routines to apply encoders and decoders. These are the core ;;;; +;;;; of the module. ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +(defun apply-encoder (objectreader ;; reader in which to look for encoder + lisp-object) ;; object to encode + (let ((tname (type-name (type-of lisp-object)))) + (cond ((not (known-type-name-p objectreader tname)) + (error + "apply-encoder: cannot encode -- unknown type ~a for object ~a~%" + tname + lisp-object)) + (t + (let ((encode-fn (get-encoder + (reader-object-encoders objectreader) + tname))) + (cond ((null encode-fn) + (error + "apply-encoder: no writer function for type ~a~%" + tname)) + (t + (funcall encode-fn lisp-object objectreader))))))) + (values)) + +(defun apply-decoder (objectreader ;; the reader in which to look + message-type-no) ;; the number of the message + (cond ((not (known-type-number-p objectreader message-type-no)) + (error + "apply-decoder: cannot decode -- unknown message type number ~d~%" + message-type-no)) + (t + (let ((decoder-struc (reader-object-decoders objectreader))) + (let ((decoder-fn (get-decoder decoder-struc message-type-no))) + (if (null decoder-fn) + (error + "apply-decoder: no reader function for type ~a~%" + (message-number-type decoder-struc message-type-no)) + (funcall decoder-fn objectreader))))))) + + + +;;;****************************************************************;;; +;;; ;;; +;;; User interface functions. ;;; +;;; ;;; +;;;****************************************************************;;; + +(defun write-object (object reader) + (apply-encoder reader object)) + +(defun write-user-object-type (object reader) + (let ((encoders (reader-object-encoders reader))) + (multiple-value-bind (encrec there) + (gethash (type-name (type-of object)) + encoders) + (if there + (let ((msgno (encoder-rec-msgtypeno encrec))) + (when (>= msgno LISP_MIN_USER_TYPE) + (C-set-message-type msgno))) + (error + "write-object: no encoder information for type ~a~%" + (type-name (type-of object))))))) + +(defun read-object (reader) + (let ((next-object-type (C-next-msg-type))) +(format t "got next type: ~A~%" (type-of next-object-type)) + (when (message-start-p next-object-type) + (setf next-object-type (C-next-type-name))) + (apply-decoder reader next-object-type))) + +(defun add-writer (reader type-no type-name writer-fn) + (add-encoder reader type-no type-name writer-fn)) + +(defun add-reader (reader type-no type-name writer-fn) + (add-decoder reader type-no type-name writer-fn)) + + + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; Readers and writers for vectors and lists. ;;;; +;;;; These should be used as default (they are, in any case, ;;;; +;;;; portable). ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; + +;(declaim (inline ok-message-type)) +(proclaim '(inline ok-message-type)) + +(defun ok-message-type (rdr type-no) + (known-type-number-p rdr type-no)) + +;;; +;;; Writer (encoder) for vectors. +;;; Vectors must be of type SIMPLE-VECTOR. +;;; + +(defun encode-vector (vec objreader) + (let ((len (length vec))) ;; get the length for the header. + ;; call the C primitive for stuffing the length + ;; into the PVM buffer + (C-obuffer-vector-header len) + ;; iterate over the vector, encoding each item and + ;; stuffing it into the buffer. + (dotimes (i len) + (apply-encoder objreader (aref vec i))) + ;; when control drops out of the bottom of this loop, + ;; the vector has been encoded. + )) + +;;; +;;; Reader (decoder) for vectors. +;;; + +(defun decode-vector (objreader) + ;; we know we have a vector, so get the length by + ;; calling the C primitive. + (let ((vector-len (C-ibuffer-vector-length))) + (cond ((minusp vector-len) + (error "Cannot read vector: negative length ~d~%" + vector-len)) + ((zerop vector-len) + (make-array '(0))) + (t + (let ((vec (make-array (list vector-len)))) + ;; create a new vector and try to fill its elements + (dotimes (i vector-len) + (let ((next-obj-type ;; get the type of the next + ;; object to be decoded from a C + ;; routine + (C-next-msg-type))) + (when (not (ok-message-type objreader next-obj-type)) + ;; call a routine to check that there is an object + ;; that comes next. + (error "Cannot read vector: invalid type ~s~%" + next-obj-type)) + (when (message-start-p next-obj-type) + (setq next-obj-type (C-next-type-name))) + (let ((next-elem (apply-decoder objreader next-obj-type))) + (setf (aref vec i) next-elem)))) + vec))))) + +;;; +;;; Writer (encoder) for lists. +;;; Lists must be PROPER lists. +;;; + +(defun encode-list (list-to-go objreader) + ;; First ensure that we have a proper list. + (unless (proper-listp list-to-go) + (error + "encode-list: input list is not proper~% ~s ~%-- cannot encode, sorry.~%" + list-to-go)) + ;; The list header should have been put into the output buffer. + ;; Remember that the end of the list has to be a nil message object. + ;; So: mark the object to go as a list by calling the C routine. + ;; (Perhaps the length could also be encoded for extra checking--- + ;; perhaps not.) + ;; OK. Run over the list and encode the elements. + (C-obuffer-list-header) + (mapc ; or dolist or explicit manipulation---it doesn't matter + #'(lambda (element) + (apply-encoder objreader element)) + list-to-go) + ;; finally, put a NIL into the output buffer to say that it's the + ;; end: do this by calling the C routine. + (C-obuffer-nil) + (values)) + +;;; +;;; Reader (decoder) for lists. +;;; + +(defun decode-list (objreader) + ;; When we're called, we know we have a list. + ;; We need to iterate until we get a nil object. + ;; (Problem: what happens if there is no nil at the end??) + (let ((newlist ()) ;; the list we're going to build. + (next-item-type ())) ;; the type of the next object in the + ;; input buffer + (loop + (setq next-item-type (C-next-msg-type)) + (when (not (ok-message-type objreader next-item-type)) + (error "cannot decode list: invalid type ~s~%" + next-item-type)) + (cond ((= next-item-type LISP_NIL_TYPE) + (return)) ; got the end of the list. + ((message-start-p next-item-type) + (setq next-item-type (C-next-type-name)) + (push (apply-decoder objreader next-item-type) newlist)) + (t + (push (apply-decoder objreader next-item-type) newlist)))) + (reverse newlist))) + + +;;;;****************************************************************;;;; +;;;; ;;;; +;;;; An example of how to define a reader and a writer for a ;;;; +;;;; structure (the same outline applies to classes). ;;;; +;;;; ;;;; +;;;;****************************************************************;;;; +#| + +(defparameter *rdr* (make-object-reader)) + +(defstruct foo slot1 slot2) + +(defconstant foo-type 32) + +(defun write-foo (obj rdr) + (write-object (foo-slot1 obj) rdr) + (write-object (foo-slot2 obj) rdr)) + +(defun read-foo (rdr) + (let ((s1 (read-object rdr)) + (s2 (read-object rdr))) + (make-foo :slot1 s1 :slot2 s2))) + +(add-writer *rdr* foo-type 'foo #'write-foo) +(add-reader *rdr* foo-type 'foo #'read-foo) +|# diff --git a/contrib/thread.patch b/contrib/thread.patch new file mode 100644 index 000000000..8bb1c1361 --- /dev/null +++ b/contrib/thread.patch @@ -0,0 +1,2062 @@ +--- src/c/error.c Mon Jun 24 04:19:09 1996 ++++ zsrc/c/error.c Mon Jul 22 18:13:48 1996 +@@ -103,10 +103,44 @@ + + object siSterminal_interrupt; + ++/* This gets _hard_ in threaded systems... */ ++/* remembering that we may be in any thread when we get this call... */ ++/* we may also _not_ be in a thread. Fortunately we can tell which */ ++/* thread we are in by examining 'active'. */ ++/* First determine where we are, if we are scheduled, or descheduled */ ++/* if descheduled, then we need to be rescheduled... */ ++/* then we can */ ++ ++#ifdef THREADS ++static bool ti_corr = 0; ++extern void *override_redirect_fun; ++extern pd *override_redirect_process; ++extern pd main_pd; ++ ++terminal_interrupt2() ++{ ++ funcall(2, siSterminal_interrupt, ti_corr? Ct : Cnil); ++} ++ ++terminal_interrupt(bool correctable) ++{ ++ ti_corr = correctable; ++ ++ start_critical_section(); ++ ++ override_redirect_process = &main_pd; ++ override_redirect_fun = terminal_interrupt2; ++ ++ force_resumption(&main_pd); ++ end_critical_section(); ++} ++ ++#else + terminal_interrupt(bool correctable) + { + funcall(2, siSterminal_interrupt, correctable? Ct : Cnil); + } ++#endif /* THREADS */ + + object + ihs_function_name(object x) +diff --recursive --unified=3 src/c/file.d zsrc/c/file.d +--- src/c/file.d Tue Mar 12 20:38:01 1996 ++++ zsrc/c/file.d Wed Jul 17 22:16:17 1996 +@@ -22,6 +22,11 @@ + + #include "config.h" + ++#ifdef THREADS ++# include ++#endif ++ ++ + #if defined(BSD) && !defined(MSDOS) + #include + #endif +@@ -347,6 +352,9 @@ + x->sm.sm_object0 = Sstring_char; + x->sm.sm_object1 = fn; + x->sm.sm_int0 = x->sm.sm_int1 = 0; ++#ifdef THREADS ++ fcntl(fileno(fp), F_SETFL, O_NONBLOCK); ++#endif + setbuf(fp, alloc_contblock(BUFSIZ)); + return(x); + } +@@ -509,6 +517,11 @@ + + #ifdef TK + bool no_input = FALSE; ++#ifdef THREADS ++# define PUTC(c, fp) lwpputc(c, fp) ++#else ++# define PUTC(c, fp) putc(c, fp) ++#endif + + StdinEnableEvents() + { +@@ -521,11 +534,24 @@ + } + # define GETC(c, fp) { if (fp == stdin) \ + while (no_input) Tk_DoOneEvent(0); \ ++#ifdef THREADS ++ c = lwpgetc(fp); \ ++#else + c = getc(fp); \ ++#endif /* THREADS */ + no_input = !FILE_CNT(fp); } + # define UNGETC(c, fp) { if (fp == stdin) no_input = FALSE; ungetc(c, fp); } + #else ++#ifdef THREADS ++# define PUTC(c, fp) lwpputc(c, fp) ++#else ++# define PUTC(c, fp) putc(c, fp) ++#endif ++#ifdef THREADS ++# define GETC(c, fp) c = lwpgetc(fp) ++#else + # define GETC(c, fp) c = getc(fp) ++#endif /* THREADS */ + # define UNGETC(c, fp) ungetc(c, fp) + #endif + +@@ -544,8 +570,11 @@ + if (fp == NULL) + closed_stream(strm); + GETC(c, fp); +-/* c &= 0377; */ +- if (feof(fp)) ++/* c &= 0377; */ ++/* if (feof(fp)) */ ++ /*c &= 0x7f; ++ printf("<%d:%c>", c, c); fflush(stdout);*/ ++ if (c == EOF) + end_of_stream(strm); + /* strm->sm.sm_int0++; useless in smm_io, Beppe */ + return(c); +@@ -612,6 +641,7 @@ + if (fp == NULL) + closed_stream(strm); + UNGETC(c, fp); ++ /* c &= 0x7f; /* hmm? */ + /* --strm->sm.sm_int0; useless in smm_io, Beppe */ + break; + +@@ -678,7 +708,7 @@ + strm->sm.sm_int1++; + if (fp == NULL) + closed_stream(strm); +- putc(c, fp); ++ PUTC(c, fp); + break; + + case smm_synonym: +@@ -921,7 +951,8 @@ + if (fp == NULL) + closed_stream(strm); + GETC(c, fp); +- if (feof(fp)) ++/* if (feof(fp)) */ ++ if (c == EOF) + return(TRUE); + else { + UNGETC(c, fp); +diff --recursive --unified=3 src/c/gbc.c zsrc/c/gbc.c +--- src/c/gbc.c Wed Jul 3 02:15:49 1996 ++++ zsrc/c/gbc.c Mon Jul 22 18:04:37 1996 +@@ -530,7 +530,7 @@ + break; + #endif CLOS + default: +- if (debug) ++ if (1 || debug) + printf("\ttype = %d\n", type_of(x)); + error("mark botch"); + } +@@ -588,10 +588,14 @@ + + #ifdef THREADS + { +- pd *pdp; ++ pd *pdp, *queue; + lpd *old_clwp = clwp; + +- for (pdp = running_head; pdp != (pd *)NULL; pdp = pdp->pd_next) { ++ queue = running_queue; ++ do { ++ pdp = queue; ++ do { ++ /*for (pdp = running_head; pdp != (pd *)NULL; pdp = pdp->pd_next) <*/ + + clwp = pdp->pd_lpd; + #endif THREADS +@@ -620,7 +624,7 @@ + mark_object(clwp->lwp_gensym_prefix); + mark_object(clwp->lwp_gentemp_prefix); + mark_object(clwp->lwp_token); +- ++ + /* (current-thread) can return it at any time + */ + mark_object(clwp->lwp_thread); +@@ -654,7 +658,48 @@ + mark_stack_conservative(cs_org, where); + } + #ifdef THREADS +- } ++ pdp = pdp->pd_next; ++ } while(pdp != queue); ++ ++ ++ /* Now I have to wonder why I didn't use an array of queues... :] */ ++ ++ if (queue == running_queue) { ++ if (blocking_queue) queue = blocking_queue; ++ else if (delayed_queue) queue = delayed_queue; ++ else if (dead_queue) queue = dead_queue; ++ else if (stopped_queue) queue = stopped_queue; ++ else if (suspended_queue) queue = suspended_queue; ++ else if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == blocking_queue) { ++ if (delayed_queue) queue = delayed_queue; ++ else if (dead_queue) queue = dead_queue; ++ else if (stopped_queue) queue = stopped_queue; ++ else if (suspended_queue) queue = suspended_queue; ++ else if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == delayed_queue) { ++ if (dead_queue) queue = dead_queue; ++ else if (stopped_queue) queue = stopped_queue; ++ else if (suspended_queue) queue = suspended_queue; ++ else if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == dead_queue) { ++ if (stopped_queue) queue = stopped_queue; ++ else if (suspended_queue) queue = suspended_queue; ++ else if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == stopped_queue) { ++ if (suspended_queue) queue = suspended_queue; ++ else if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == suspended_queue) { ++ if (waiting_queue) queue = waiting_queue; ++ else queue = NULL; ++ } else if (queue == waiting_queue) ++ queue = NULL; ++ } while(queue != NULL); + clwp = old_clwp; + } + #endif THREADS +@@ -853,9 +898,9 @@ + if (val == 0) { + /* informations used by the garbage collector need to be updated */ + # ifdef __linux +- running_head->pd_env[0].__jmpbuf[0].__sp = old_env[0].__jmpbuf[0].__sp; ++ running_queue->pd_env[0].__jmpbuf[0].__sp = old_env[0].__jmpbuf[0].__sp; + # else +- running_head->pd_env[JB_SP] = old_env[JB_SP]; ++ running_queue->pd_env[JB_SP] = old_env[JB_SP]; + # endif + old_clwp = clwp; + Values = main_lpd.lwp_Values; +Only in zsrc/c: gbc.my +diff --recursive --unified=3 src/c/load.d zsrc/c/load.d +--- src/c/load.d Tue Mar 12 20:40:01 1996 ++++ zsrc/c/load.d Wed Jul 17 17:55:13 1996 +@@ -31,7 +31,9 @@ + extern object Kwild; + extern object Vdefault_pathname_defaults; + extern object Vpackage; ++#ifndef THREADS + extern object Vstandard_output; ++#endif + extern object readc(); + + /******************************* ------- ******************************/ +diff --recursive --unified=3 src/c/lwp.d zsrc/c/lwp.d +--- src/c/lwp.d Thu Jun 27 17:43:28 1996 ++++ zsrc/c/lwp.d Mon Jul 22 18:14:34 1996 +@@ -3,6 +3,7 @@ + */ + /* + Copyright (c) 1990, Giuseppe Attardi. ++ Copyright (c) 1996, Brian Spilsbury. + + ECoLisp is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public +@@ -12,18 +13,43 @@ + See file '../Copyright' for full details. + */ + ++/* ++ Rewritten to use a multiple queue scheme to reduce time, and ++ facilitate simulated blocking io, and sleeping without ++ busy-looping. ++ Changed timing to be millisecond standard. ++ Made (sleep) equivelent to (%delay). ++ added lwpgetc(), lwpputc(), lwpread(), lwpwrite() to provide ++ for transparent blocking character and sequence io. lwpread, and ++ lwpwrite aren't used yet. ++ Made all streams non-blocking. ++ ++ Brian Spilsbury, 1996. ++*/ + + #include "config.h" + ++#include ++ + /******************************* EXPORTS ******************************/ + + lpd main_lpd; + lpd *clwp = &main_lpd; + int critical_level = 0; +-pd *running_head; /* front of running pd's */ +-pd *running_tail; /* back of running pd's */ ++ + pd main_pd; + ++pd *active = &main_pd; /* the pd that is attached to clwp */ ++ ++ /* circular queues, no tails */ ++pd *running_queue; /* running pd's */ ++pd *blocking_queue; /* blocking pd's */ ++pd *delayed_queue; /* delaying pd's */ ++pd *dead_queue; /* dead pd's */ ++pd *stopped_queue; /* stopped pd's */ ++pd *suspended_queue; /* suspended pd's */ ++pd *waiting_queue; /* waiting pd's */ ++ + /******************************* IMPORTS ******************************/ + + extern scheduler_interruption; /* in unixint.c */ +@@ -37,27 +63,41 @@ + #define thread_switch() { setTimer(0); enable_scheduler(); \ + scheduler(0, 0, NULL); } + +-static bool timer_active = FALSE; +-static bool scheduler_disabled = FALSE; ++static int timer_active = FALSE; ++static int scheduler_disabled = FALSE; + static int scheduler_level = 0; /* tito */ +-static bool reset_timer = FALSE; ++static int reset_timer = FALSE; + static int running_processes = 1; ++static int awake_processes = 1; + static int absolute_time = 0; ++static int housekeeping_time = 0; ++static int fd_hightide = 3; /* highest fd ever to block + 1 */ ++static int wake_lowtide = -1; /* time to closest sleep-wake */ ++ ++/* hopefully this will work with DJGPP, but I really have no idea... */ ++/* Sets for blocking threads, see housekeeping */ ++static fd_set fd_rd, fd_wr, fd_ex; + + object Srunning; + object Ssuspended; + object Swaiting; + object Sstopped; + object Sdead; ++object Sblocking; ++object Sdelayed; + object siSthread_top_level; + ++void (*override_redirect_fun)() = NULL; ++pd *override_redirect_process = NULL; ++ + static object main_thread; + + static + setTimer(long time) + { +- struct itimerval oldtimer; +- struct itimerval itimer; ++ static struct itimerval oldtimer; ++ static struct itimerval itimer; ++ + itimer.it_value.tv_sec = 0; + itimer.it_value.tv_usec = time; + itimer.it_interval.tv_sec = 0; +@@ -66,32 +106,25 @@ + } + + pd * +-dequeue() +-{ +- pd *tmp; +- tmp = running_head; +- if (running_head != NULL) +- running_head = running_head->pd_next; +- return tmp; +-} +- +-pd * +-make_pd() ++make_pd(pd *o) + { + pd *new_pd; lpd *npd; + + /* Allocate a new descriptor for the new lwp */ +- new_pd = (pd *)malloc(sizeof(pd)); ++ /* if we already have one, then we have passed it in o... */ ++ ++ if (o) new_pd = o; ++ else new_pd = (pd *)malloc(sizeof(pd)); + + /* create a new stack ... */ +- new_pd->pd_base = (int *)malloc(STACK_SIZE * sizeof(int)); +- new_pd->pd_status = SUSPENDED; ++ if (!o) new_pd->pd_base = (int *)malloc(STACK_SIZE * sizeof(int)); + + /* allocate a lisp descriptor: + * using the calloc here it's possible to avoid the + * critical section in the various push operations + */ +- npd = new_pd->pd_lpd = (lpd *)calloc(sizeof(lpd), 1); ++ if (o) { npd = new_pd->pd_lpd; } ++ else npd = new_pd->pd_lpd = (lpd *)calloc(1, sizeof(lpd)); + + /* initialize it */ + +@@ -117,11 +150,13 @@ + npd->lwp_frs_top = npd->lwp_frame_stack - 1; + npd->lwp_frs_limit = npd->lwp_frame_stack + FRSSIZE; + ++ /* constants are fine for a reincarnatee */ + npd->lwp_alloc_temporary = OBJNULL; + npd->lwp_backq_level = 0; + npd->lwp_eval1 = 0; + /* for gc */ +- npd->lwp_fmt_temporary_stream = OBJNULL; ++ /* we need to rebuild temporary_stream for some reason */ ++ if (!o) npd->lwp_fmt_temporary_stream = OBJNULL; + npd->lwp_fmt_temporary_string = OBJNULL; + + npd->lwp_PRINTstream = Cnil; +@@ -153,7 +188,7 @@ + npd->lwp_string_register = OBJNULL; + npd->lwp_gensym_prefix = OBJNULL; + npd->lwp_gentemp_prefix = OBJNULL; +- npd->lwp_token = OBJNULL; ++ if (!o) npd->lwp_token = OBJNULL; + + /* lex_env copy */ + npd->lwp_lex[0] = lex_env[0]; +@@ -168,70 +203,30 @@ + /* Now the allocation. If the gc is invoked we are able to mark + * the objects already allocated + */ +- npd->lwp_fmt_temporary_stream = make_string_output_stream(64); +- npd->lwp_fmt_temporary_string = +- npd->lwp_fmt_temporary_stream->sm.sm_object0; +- +- npd->lwp_string_register = alloc_simple_string(0); +- npd->lwp_gensym_prefix = make_simple_string("G"); +- npd->lwp_gentemp_prefix = make_simple_string("T"); +- npd->lwp_token = alloc_simple_string(LISP_PAGESIZE); +- npd->lwp_token->st.st_self = alloc_contblock(LISP_PAGESIZE); ++ ++ /* Hmm, this gets more complex with a reincarnatee */ ++ /* ideally we just want to initialize these destructively */ ++ /* and hope that this is good enough. */ ++ /* The main problem is that if other things have been passed these */ ++ /* and don't expect them to suddenly change, but I'm not sure that this */ ++ /* can be the case, since these should be local to a thread... */ ++ ++ if (!o) npd->lwp_fmt_temporary_stream = make_string_output_stream(64); ++ /* might need some resetting here? */ ++ npd->lwp_fmt_temporary_string = npd->lwp_fmt_temporary_stream->sm.sm_object0; ++ ++ if (!o) npd->lwp_string_register = alloc_simple_string(0); ++ if (!o) npd->lwp_gensym_prefix = make_simple_string("G"); ++ if (!o) npd->lwp_gentemp_prefix = make_simple_string("T"); ++ if (!o) npd->lwp_token = alloc_simple_string(LISP_PAGESIZE); ++ if (!o) npd->lwp_token->st.st_self = alloc_contblock(LISP_PAGESIZE); + npd->lwp_token->st.st_fillp = 0; + npd->lwp_token->st.st_hasfillp = TRUE; + npd->lwp_token->st.st_adjustable = TRUE; +- +- return new_pd; +-} +- +-update_queue() +-{ +- register pd *dead_pd; +- pd *last = running_tail; +- +- do +- switch (running_head->pd_status) { +- +- case DEAD: +- +- /* remove the dead process */ +- dead_pd = dequeue(); +- /* free the lisp descriptor */ +- free(dead_pd->pd_lpd); +- /* free the memory allocated for the stack and the descriptor */ +- free(dead_pd->pd_base); +- free(dead_pd); +- break; +- +-/* case SUSPENDED: */ +- case DELAYED: +- +- if (running_head->pd_slice != 0) +- if (absolute_time > running_head->pd_slice) { +- +- /* the time slice has expired */ +- running_head->pd_slice = 0; + +- if ((running_head->pd_thread->th.th_cont) != OBJNULL) { +- /* in this case a continuation was created before %delay */ +- running_head->pd_thread->th.th_cont->cn.cn_timed_out = TRUE; +- running_head->pd_thread->th.th_cont = OBJNULL; +- } +- running_head->pd_status = RUNNING; +- return; /* now you are a running process */ +- } +- ROTQUEUE(); +- break; +- +- case WAITING: /* waiting processes need to be scheduled */ +- case RUNNING: +- return; /* found schedulable process */ +- +- default: /* currently is only STOPPED */ +- ROTQUEUE(); +- break; +- } +- while (running_head != last); ++ new_pd->pd_status = SUSPENDED; ++ ENQUEUE(new_pd, suspended_queue); /* needs to be on a queue */ ++ return new_pd; + } + + activate_thread(object thread) +@@ -275,33 +270,111 @@ + sigsetmask(sigblock(0) & ~(sigmask(SIGALRM))); + #endif + ++/* to get here we've been scheduled */ ++/* so we aren't in someone else's bind stack */ ++/* so we should get the defaults for the stdio */ ++ ++start_critical_section(); ++ ++for(;;) { /* mortal coil */ ++ /* set up local stdio bindings below everything else on the bind stack */ ++ /* so that they shouldn't be take out of scope ever... */ ++ ++ bind_var(Vstandard_input, SYM_VAL(Vstandard_input), Cnil); ++ bind_var(Vstandard_output, SYM_VAL(Vstandard_output), Cnil); ++ bind_var(Verror_output, SYM_VAL(Verror_output), Cnil); ++ bind_var(Vquery_io, SYM_VAL(Vquery_io), Cnil); ++ bind_var(Vdebug_io, SYM_VAL(Vdebug_io), Cnil); ++ bind_var(Vterminal_io, SYM_VAL(Vterminal_io), Cnil); ++ bind_var(Vtrace_output, SYM_VAL(Vtrace_output), Cnil); ++ + { int i; +- for (i = clwp->lwp_nValues; i > 0;) ++ for (i = clwp->lwp_nValues; i > 0;) + VALUES(i) = VALUES(--i); + VALUES(0) = clwp->lwp_thread->th.th_fun; ++ end_critical_section(); + apply(clwp->lwp_nValues+1, siSthread_top_level, &VALUES(0)); ++ start_critical_section(); + } + /* Termination */ +- +- terpri(Cnil); +- running_head->pd_status = DEAD; +- running_head->pd_thread->th.th_self = NULL; ++ ++ { ++ pd *tmp = active; ++ ++ tmp->pd_status = DEAD; + running_processes--; ++ awake_processes--; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, dead_queue); ++ } + +- update_queue(); +- thread_next(); /* update_queue has freed our stack!!! */ ++ end_critical_section(); ++ thread_switch(); /* stack won't have been free'd yet... that's a */ ++ /* job for housekeeping to think about. */ ++ /* otherwise dead threads live in limbo waiting */ ++ /* for reincarnation */ ++ /* incase we are raised from the dead, we want to do it again */ ++ start_critical_section(); ++ } + } + + /* +- * switch to the first thread on queue ++ * switch to the next thread on queue + */ + thread_next() + { ++ /* rotate the running-queue */ ++ ++ /* should devolve into an if, but *shrug* better to guarantee */ ++ start_critical_section(); ++ ++ if (override_redirect_process == active) { ++ void (*fun)(); ++ ++ force_resumption(active); ++ ++ if (running_processes > 1) { ++ timer_active = TRUE; ++ setTimer(REALQUANTUM); ++ } else { ++ timer_active = FALSE; ++ absolute_time = 0; ++ } ++ fun = override_redirect_fun; ++ ++ override_redirect_fun = NULL; ++ override_redirect_process = NULL; ++ ++ end_critical_section(); ++ (*fun)(); ++ start_critical_section(); ++ } ++ + /* unwind the bind stack */ + lwp_bds_unwind(clwp->lwp_bind_stack, clwp->lwp_bds_top); + ++ ROTQUEUE(running_queue); ++ ++ end_critical_section(); ++ /* housekeeping isn't actually critical */ ++ /* and turns off the timer while its in there */ ++ if (absolute_time > housekeeping_time) ++ housekeeping(); ++ ++ /* we need this incase a signal blew us out of the previous housekeeping */ ++ /* and running_queue is void */ ++ ++ while(running_queue == NULL) { ++ static struct timeb tb; ++ ftime(&tb); /* not sure how portable */ ++ absolute_time = tb.millitm + tb.time*1000; ++ housekeeping(); ++ } ++ start_critical_section(); ++ + /* switch clwp */ +- clwp = running_head->pd_lpd; ++ clwp = running_queue->pd_lpd; ++ active = running_queue; + + /* restore Values pointer */ + Values = clwp->lwp_Values; +@@ -313,19 +386,253 @@ + if (running_processes > 1) { + timer_active = TRUE; + setTimer(REALQUANTUM); +- } else { ++ } else { + timer_active = FALSE; + absolute_time = 0; + } +- siglongjmp(running_head->pd_env, 1); ++ ++ end_critical_section(); ++ siglongjmp(active->pd_env, 1); + } + + /* + * Called when time slice expires or explicitily to switch thread ++ * New version... + */ + scheduler(int sig, int code, struct sigcontext *scp) + { + int val; ++ static struct timeb tb; ++ ++#if defined(SYSV) || defined(__svr4__) || defined(__linux) ++ signal(SIGALRM, scheduler); ++#endif SYSV ++ ++ ftime(&tb); /* not sure how portable */ ++ absolute_time = tb.millitm + tb.time*1000; ++ ++ if (critical_level > 0) { /* within critical section */ ++ scheduler_interrupted = TRUE; ++ scheduler_interruption = SCHEDULER_INT; ++ return; ++ } ++ if (scheduler_level > 0) { /* abilitation check */ ++ scheduler_interrupted = TRUE; ++ return; ++ } ++ ++ val = sigsetjmp(active->pd_env, 1); ++ ++ if (val == 1) /* resume interrupted thread execution */ ++ return; /* coming back from longjmp in thread_next */ ++ ++ if (val == 2) /* coming back from longjmp in GC */ ++ gc(garbage_parameter); /* GC will return to the previous thread */ ++ ++ thread_next(); ++} ++ ++/* TODO: Add in waiting thread condition resolution */ ++housekeeping() ++{ ++ static struct timeval timeout; ++ static pd *p, *q; ++ static int tide; ++ static fd_set rd, wr, ex; ++ /* see if we are polling or lurking */ ++ ++ /* turn off that bloody timer... */ ++ setTimer(0); ++ ++ if ((running_processes > 1) && (awake_processes > 0)) { ++ /* poll */ ++ /* set timeout to instant */ ++ timeout.tv_sec = timeout.tv_usec = 0; ++ tide = 1; ++ } else { ++ /* is recovery possible? */ ++ ++ if ( (running_queue == NULL) && ++ (blocking_queue == NULL) && ++ (delayed_queue == NULL)) { ++ /* in a coma... can't awaken itself... */ ++ /* there is a possibility that a signal */ ++ /* will, but um, for now assume dead and buried */ ++ exit(0); /* bail w/out error */ ++ } ++ ++ /* ok, in theory we can wake up.... so lurk */ ++ /* set timeout to the shortest sleep resumption time */ ++ /* if there isn't a sleep resumption time */ ++ /* block forever... */ ++ ++ if (wake_lowtide != -1) { ++ if (absolute_time >= wake_lowtide) { ++ timeout.tv_sec = timeout.tv_usec = 0; ++ tide = 1; ++ } else { ++ timeout.tv_sec = (wake_lowtide-absolute_time)/1000; ++ timeout.tv_usec = ((wake_lowtide-absolute_time)%1000)*1000; ++ tide = 1; ++ } ++ } else tide = 0; ++ } ++ ++ memcpy(&rd, &fd_rd, sizeof(fd_set)); ++ memcpy(&wr, &fd_wr, sizeof(fd_set)); ++ memcpy(&ex, &fd_ex, sizeof(fd_set)); ++ ++ /* If there is an error, the sets are undefined, just bail out... */ ++ /* we'll catch it next time, it was probably a signal interrupting */ ++ /* us. */ ++ if (select(fd_hightide, &rd, &wr, &ex, (tide ? &timeout : NULL)) == -1) { ++ /* we broke for some reason */ ++ /* a signal handler may have been invoked... */ ++ /* someone may have been woken up */ ++ /* so schedule another housekeeping apointment */ ++ /* and bail */ ++ goto out; ++ } ++ ++ /* check for awakened threads */ ++ ++ if (p = blocking_queue) ++ do { ++ q = p->pd_next; ++ switch(p->pd_fp_mode) { ++ case PD_INPUT: ++ if (FD_ISSET(fileno(p->pd_fp), &rd)) { ++ FD_CLR(fileno(p->pd_fp), &fd_rd); ++ DEQUEUE(p, blocking_queue); ++ ENQUEUE(p, running_queue); ++ p->pd_status = RUNNING; ++ awake_processes++; ++ if (blocking_queue == NULL) goto endblk; ++ } ++ break; ++ case PD_OUTPUT: ++ if (FD_ISSET(fileno(p->pd_fp), &wr)) { ++ FD_CLR(fileno(p->pd_fp), &fd_wr); ++ DEQUEUE(p, blocking_queue); ++ ENQUEUE(p, running_queue); ++ p->pd_status = RUNNING; ++ awake_processes++; ++ if (blocking_queue == NULL) goto endblk; ++ } ++ break; ++ case PD_EXCEPTION: ++ if (FD_ISSET(fileno(p->pd_fp), &ex)) { ++ FD_CLR(fileno(p->pd_fp), &fd_ex); ++ DEQUEUE(p, blocking_queue); ++ ENQUEUE(p, running_queue); ++ p->pd_status = RUNNING; ++ awake_processes++; ++ if (blocking_queue == NULL) goto endblk; ++ } ++ break; ++ } ++ p = q; ++ } while(p != blocking_queue); ++ ++ /* if sleeping, check for wakeup.... */ ++ ++endblk: tide = -1; ++ ++ /*putchar('.'); fflush(stdout);*/ ++ ++ if ((wake_lowtide != -1) && ((p = delayed_queue) != NULL)) ++ do { ++ q = p->pd_next; ++ if (absolute_time >= p->pd_slice) { ++ DEQUEUE(p, delayed_queue); ++ ENQUEUE(p, running_queue); ++ p->pd_status = RUNNING; ++ awake_processes++; ++ if (delayed_queue == NULL) break; ++ } else { ++ /* get new low-tide */ ++ if ((tide == -1) || (p->pd_slice < tide)) ++ tide = p->pd_slice; ++ } ++ ++ p = q; ++ } while(p != delayed_queue); ++ ++ wake_lowtide = tide; ++ ++ /* requeue waiting threads for resolution checking */ ++ /* not a good solution, but the only one that I can see */ ++ /* at least now we will only check them on housekeeping intervals */ ++ /* just get the timeout cases to set the wake_lowtide on entry */ ++ /* to prevent oversleeping. */ ++ ++ while(p = waiting_queue) { ++ DEQUEUE(p, waiting_queue); ++ ENQUEUE(p, running_queue); ++ p->pd_status = RUNNING; ++ awake_processes++; ++ } ++ ++out: housekeeping_time = absolute_time + 1000; /* one second */ ++} ++ ++/* this will mostly be used in conjunction with override_redirect */ ++/* which should be set before entry here. */ ++ ++force_resumption(pd *p) ++{ ++ start_critical_section(); ++ ++ switch(p->pd_status) { ++ case RUNNING: DEQUEUE(p, running_queue); ++ break; ++ case STOPPED: DEQUEUE(p, stopped_queue); ++ running_processes++; ++ awake_processes++; ++ break; ++ case SUSPENDED: DEQUEUE(p, stopped_queue); ++ running_processes++; ++ awake_processes++; ++ break; ++ case DEAD: /* hmmm... raising the dead might be dangerous */ ++ running_processes++; ++ awake_processes++; ++ DEQUEUE(p, dead_queue); ++ break; ++ case WAITING: DEQUEUE(p, waiting_queue); ++ awake_processes++; ++ break; ++ case DELAYED: DEQUEUE(p, delayed_queue); ++ awake_processes++; ++ break; ++ /* don't worry about the magic, at worst this can */ ++ running_processes++; ++ /* cause housekeeping to make a false check */ ++ case BLOCKED: DEQUEUE(p, blocking_queue); ++ /* this needs some fixing */ ++ switch(p->pd_fp_mode) { ++ case PD_INPUT: ++ FD_CLR(fileno(p->pd_fp), &fd_rd); ++ break; ++ case PD_OUTPUT: ++ FD_CLR(fileno(p->pd_fp), &fd_wr); ++ break; ++ case PD_EXCEPTION: ++ FD_CLR(fileno(p->pd_fp), &fd_ex); ++ break; ++ } ++ awake_processes++; ++ break; ++ } ++ ++ ENQUEUE(p, running_queue); ++ end_critical_section(); ++} ++ ++#ifdef 0 ++scheduler(int sig, int code, struct sigcontext *scp) ++{ ++ int val; + + #if defined(SYSV) || defined(__svr4__) || defined(__linux) + signal(SIGALRM, scheduler); +@@ -342,7 +649,7 @@ + return; + } + +- val = sigsetjmp(running_head->pd_env, 1); ++ val = sigsetjmp(running_dead->pd_env, 1); + + if (val == 1) /* resume interrupted thread execution */ + return; /* coming back from longjmp in thread_next */ +@@ -353,6 +660,7 @@ + ROTQUEUE(); + thread_next(); + } ++#endif /* old version */ + + /* + * Handle signal received within critical section +@@ -400,18 +708,34 @@ + register pd *p; + + start_critical_section(); +- running_processes++; ++ ++ if (rpd->pd_status == STOPPED) { ++ DEQUEUE(rpd, stopped_queue); ++ running_processes++; ++ awake_processes++; ++ } else if (rpd->pd_status == DELAYED) { ++ DEQUEUE(rpd, delayed_queue); ++ /* TODO: look for interaction with housekeeping problem for this case... */ ++ awake_processes++; ++ } else if (rpd->pd_status == SUSPENDED) { ++ DEQUEUE(rpd, suspended_queue); ++ running_processes++; ++ awake_processes++; ++ } ++ ++ /* else, should we be here? no. hmmm. */ ++ /* where are the fucking arguments? */ + + rpd->pd_status = RUNNING; +- for (p = running_head; (p != rpd) && (p != NULL); p = p->pd_next) ; +- if (p == NULL) +- ENQUEUE(rpd); ++ ++ ENQUEUE(rpd, running_queue); ++ + end_critical_section(); + + if (!timer_active) { + timer_active = TRUE; + setTimer(REALQUANTUM); +- } ++ } + } + + /*********** +@@ -428,6 +752,11 @@ + RETURN(1); + } + ++/* Hmmmmm, what the hell is this supposed to do? */ ++/* and why bother? */ ++/* Put this in the TODO basket, as something of dubiousness */ ++ ++#ifdef 0 + siLthread_break_quit(int narg) + { + /* reset everything in MT */ +@@ -443,17 +772,21 @@ + critical_level = 0; + scheduler_interrupted = 0; + +- for (p = running_head; (p != NULL); p = p->pd_next) +- if (p != &main_pd) ++ /*for (p = running_dead; (p != NULL); p = p->pd_next)*/ ++ p = running_queue; ++ do { ++ if (p != &main_pd) { + p->pd_status = DEAD; +- else { ++ } else { + p->pd_status = RUNNING; + p->pd_thread->th.th_cont = OBJNULL; +- } ++ } ++ p = p->pd_next; ++ } while(running_queue->pd_next != running_queue); + +- if (running_head != &main_pd) { ++ if (running_queue != &main_pd) { + update_queue(); +- thread_next(); ++ thread_dext(); + /* here one should deallocate the main-thread function */ + } + else +@@ -462,6 +795,7 @@ + VALUES(0) = Cnil; + RETURN(1); + } ++#endif + + siLthread_break_resume(int narg) + { +@@ -478,16 +812,70 @@ + Lthread_list(int narg) + { + pd *p; +- object tmp, x = CONS(running_head->pd_thread, Cnil); ++ object tmp; ++ object tmp2 = CONS(running_queue->pd_thread, Srunning); ++ object x = CONS(tmp2, Cnil); + + tmp = x; + + start_critical_section(); + +- for (p = running_head->pd_next; (p != NULL); p = p->pd_next) { +- CDR(tmp) = CONS(p->pd_thread, Cnil); +- tmp = CDR(tmp); +- } ++ p = running_queue->pd_next; ++ while(p != running_queue) { ++ tmp2 = CONS(p->pd_thread, Srunning); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ tmp = CDR(tmp); ++ p = p->pd_next; ++ } ++ ++ if (p = blocking_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Sblocking); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != blocking_queue); ++ ++ if (p = delayed_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Sdelayed); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != delayed_queue); ++ ++ /* TODO: Should this queue be listed? */ ++ if (p = dead_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Sdead); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != dead_queue); ++ ++ if (p = stopped_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Sstopped); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != stopped_queue); ++ ++ if (p = suspended_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Ssuspended); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != suspended_queue); ++ ++ if (p = waiting_queue) ++ do { ++ tmp2 = CONS(p->pd_thread, Swaiting); ++ CDR(tmp) = CONS(tmp2, Cnil); ++ p = p->pd_next; ++ tmp = CDR(tmp); ++ } while(p != waiting_queue); + + end_critical_section(); + +@@ -511,20 +899,41 @@ + /* fun = SYM_FUN(fun); confusing */ + } + +- x = alloc_object(t_thread); +- x->th.th_fun = fun; +- x->th.th_size = sizeof(pd); +- x->th.th_self = npd = make_pd(); +- x->th.th_cont = OBJNULL; ++start_critical_section(); ++ /* see if there is a lost soul waiting for reincarnation */ ++ if (dead_queue) { ++ /* ok, lets juice it up */ ++ ++ npd = dead_queue; ++ DEQUEUE(npd, dead_queue); ++ ++ x = npd->pd_lpd->lwp_thread; ++ /* enqueued in make_pd */ ++ ++ x->th.th_fun = fun; ++ x->th.th_size = sizeof(pd); ++ x->th.th_self = make_pd(npd); /* reinitialize it */ ++ x->th.th_cont = OBJNULL; ++ } else { ++ /* ok, no lost souls, better build a new one */ ++ x = alloc_object(t_thread); ++ x->th.th_fun = fun; ++ x->th.th_size = sizeof(pd); ++ x->th.th_self = npd = make_pd(0); ++ x->th.th_cont = OBJNULL; + +- npd->pd_thread = x; +- npd->pd_slice = 0; ++ npd->pd_thread = x; ++ npd->pd_slice = 0; + +- /* Backpointer to thread */ +- npd->pd_lpd->lwp_thread = x; ++ /* Backpointer to thread */ ++ npd->pd_lpd->lwp_thread = x; + + activate_thread(x); ++ } ++ ++ /* note: this is created as a suspended thread, and in that queue */ + ++end_critical_section(); + VALUES(0) = x; + RETURN(1); + } +@@ -542,12 +951,17 @@ + start_critical_section(); /* tito */ + thread->th.th_self->pd_status = STOPPED; + running_processes--; +- if (thread->th.th_self == running_head) { +- critical_level--; /* end_critical_section() */ +- update_queue(); +- thread_next(); +- } else +- end_critical_section(); ++ awake_processes--; ++ if (thread->th.th_self == active) { ++ DEQUEUE(thread->th.th_self, running_queue); ++ ENQUEUE(thread->th.th_self, stopped_queue); ++ critical_level--; /* end_critical_section() */ ++ thread_switch(); ++ } else { ++ DEQUEUE(thread->th.th_self, running_queue); ++ ENQUEUE(thread->th.th_self, stopped_queue); ++ end_critical_section(); ++ } + VALUES(0) = Cnil; + RETURN(1); + } +@@ -568,6 +982,7 @@ + start_critical_section(); /* tito */ + thread->th.th_self->pd_status = RUNNING; + running_processes++; ++ awake_processes++; + + if (!timer_active) { + timer_active = TRUE; +@@ -582,11 +997,8 @@ + + Lkill_thread(int narg, object thread) + { ++ pd *tmp; + +- /* The following code is not enough. +- Consider: The scheduler can be disabled +- What about killing the current thread? +- */ + check_arg(1); + + if (type_of(thread) != t_thread) +@@ -597,13 +1009,17 @@ + thread->th.th_self->pd_status = DEAD; + if (thread->th.th_self->pd_lpd == clwp) { + /* if a thread kills itself the scheduler is to be called */ +- thread->th.th_self = NULL; ++ tmp = thread->th.th_self; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, dead_queue); + critical_level--; /* end_critical_section() */ +- update_queue(); +- thread_next(); ++ thread_switch(); + } + else { +- thread->th.th_self = NULL; ++ /*thread->th.th_self = NULL;*/ ++ tmp = thread->th.th_self; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, dead_queue); + end_critical_section(); + } + } +@@ -642,6 +1058,11 @@ + case DEAD: + VALUES(0) = Sdead; + break; ++ case BLOCKED: ++ VALUES(0) = Sblocking; ++ break; ++ case DELAYED: ++ VALUES(0) = Sdelayed; + default: + FEerror("Unexpected type for thread ~A", 1, thread); + } +@@ -663,6 +1084,7 @@ + object x; + check_arg(1); + ++ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + +@@ -797,91 +1219,206 @@ + check_arg(0); + + if (timer_active) { +- running_head->pd_status = SUSPENDED; ++ pd *tmp = active; ++ tmp->pd_status = SUSPENDED; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, suspended_queue); + running_processes--; ++ awake_processes--; + thread_switch(); + /* When resumed it will be provided with the Values to return */ +- RETURN(running_head->pd_lpd->lwp_nValues); ++ RETURN(tmp->pd_lpd->lwp_nValues); + } + else + FEerror("No other active thread.", 0); + } + ++void lwpblockon(pd *who, FILE *fp, int mode) ++{ ++ who->pd_fp = fp; ++ who->pd_fp_mode = mode; /* in, out, execept */ ++ who->pd_status = BLOCKED; ++ ++ start_critical_section(); ++ ++ DEQUEUE(who, running_queue); ++ ENQUEUE(who, blocking_queue); ++ awake_processes--; ++ ++ if (fd_hightide <= fileno(fp)) ++ fd_hightide = fileno(fp)+1; ++ ++ switch(mode) { ++ case PD_INPUT: ++ FD_SET(fileno(fp), &fd_rd); ++ break; ++ case PD_OUTPUT: ++ FD_SET(fileno(fp), &fd_wr); ++ break; ++ case PD_EXCEPTION: ++ FD_SET(fileno(fp), &fd_ex); ++ break; ++ } ++ ++ end_critical_section(); ++ ++ thread_switch(); ++} ++ ++int inline lwpgetc(FILE *fp) ++{ ++ int c; ++ ++loop: errno = 0; ++ c = getc(fp); ++ if (errno) { ++ lwpblockon(active, fp, PD_INPUT); ++ clearerr(fp); ++ goto loop; ++ } ++ return(c); ++} ++ ++void inline lwpputc(char c, FILE *fp) ++{ ++loop: errno = 0; ++ putc(c, fp); ++ if (errno) { ++ lwpblockon(active, fp, PD_OUTPUT); ++ clearerr(fp); ++ goto loop; ++ } ++ return; ++} ++ ++int inline lwpread(char *buf, int len, FILE *fp) ++{ ++ int ind = 0, left = len, n; ++ ++loop: errno = 0; ++ n = read(&buf[ind], left, fileno(fp)); ++ if (errno) { ++ ind += n; ++ left -= n; ++ lwpblockon(active, fp, PD_INPUT); ++ clearerr(fp); ++ goto loop; ++ } ++ return(ind+n); ++} ++ ++int inline lwpwrite(char *buf, int len, FILE *fp) ++{ ++ int ind = 0, left = len, n; ++ ++loop: errno = 0; ++ n = write(&buf[ind], left, fileno(fp)); ++ if (errno) { ++ ind += n; ++ left -= n; ++ lwpblockon(active, fp, PD_OUTPUT); ++ clearerr(fp); ++ goto loop; ++ } ++ return(ind+n); ++} ++ + Ldelay(int narg, object interval) + { int z; + + check_arg(1); + check_type_non_negative_integer(&interval); + z = fix(interval); ++ ++ if (timer_active) { ++ pd *tmp = active; /* remember who we are */ ++ lwpsleep(z*1000); /* lwpsleep is in milliseconds */ ++ /* When resumed it will be provided with the Values to return */ ++ RETURN(tmp->pd_lpd->lwp_nValues); ++ } ++ else ++ { ++ sleep(z); ++ } ++} ++ ++/* Sleep for at least ms milliseconds */ ++lwpsleep(int ms) ++{ + + if (timer_active) { +- running_head->pd_status = DELAYED; +- running_processes--; ++ pd *tmp = active; ++ ++ start_critical_section(); ++ tmp->pd_status = DELAYED; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, delayed_queue); ++ awake_processes--; + +- /* Translate seconds in number of scheduler slices */ +- running_head->pd_slice = z * 10 + absolute_time; ++ tmp->pd_slice = ms + absolute_time; ++ ++ if ((wake_lowtide == -1) || (wake_lowtide > tmp->pd_slice)) ++ wake_lowtide = tmp->pd_slice; ++ ++ end_critical_section(); + + thread_switch(); +- +- /* When resumed it will be provided with the Values to return */ +- RETURN(running_head->pd_lpd->lwp_nValues); + } +- else +- sleep(z); ++ else usleep(ms*1000); /* milli->micro */ + } + ++/* TODO: Find a way to move this functionality into housekeeping() ++ sigh */ ++ + Lthread_wait(int narg, object fun, ...) + { int nr; ++ pd *tmp = active; + va_list args; + va_start(args, fun); +- ++ + if (narg < 1) FEtoo_few_arguments(&narg); + +- start_critical_section(); +- running_head->pd_status = WAITING; +- running_processes--; +- end_critical_section(); +- + for (;;) { + + nr = apply(narg-1, fun, args); + + if (VALUES(0) != Cnil) + break; +- else if (timer_active) { +- /* the time slice has not been used */ +- absolute_time--; +- thread_switch(); +- } else +- FEerror("The condition will never be satisfied for lack of active processes", 0); ++ ++ start_critical_section(); ++ tmp->pd_status = WAITING; ++ ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, waiting_queue); ++ ++ awake_processes--; ++ ++ end_critical_section(); ++ thread_switch(); + } +- running_head->pd_status = RUNNING; +- running_processes++; +- end_critical_section(); ++ + RETURN(nr); + } + +- ++/* TODO: whack this into housekeeping() */ ++ + Lthread_wait_with_timeout(int narg, object timeout, object fun, ...) + { + int nr; ++ pd *tmp = active; + va_list args; + va_start(args, fun); + + if (narg < 2) FEtoo_few_arguments(&narg); + check_type_non_negative_integer(&timeout); + +- /* We have to translate seconds in scheduler call number */ +- start_critical_section(); +- running_head->pd_slice = fix(timeout) * 10 + absolute_time; ++ /* We have to translate seconds into milliseconds into the future */ ++ tmp->pd_slice = fix(timeout) * 1000 + absolute_time; + +- running_head->pd_status = WAITING; +- running_processes--; +- end_critical_section(); + + for (;;) { + +- if (absolute_time > running_head->pd_slice) { ++ if (absolute_time > tmp->pd_slice) { + /* the time slice has expired */ + VALUES(0) = Cnil; + nr = 1; +@@ -897,13 +1434,19 @@ + absolute_time--; + thread_switch(); + } +- } ++ ++ tmp->pd_status = WAITING; ++ DEQUEUE(tmp, running_queue); ++ ENQUEUE(tmp, waiting_queue); ++ awake_processes--; ++ ++ if ((wake_lowtide == -1) || (wake_lowtide > tmp->pd_slice)) ++ wake_lowtide = tmp->pd_slice; ++ ++ thread_switch(); ++ } + +- start_critical_section(); +- running_head->pd_slice = 0; +- running_head->pd_status = RUNNING; +- running_processes++; +- end_critical_section(); ++ tmp->pd_slice = 0; + RETURN(nr); + } + +@@ -912,11 +1455,25 @@ + signal(SIGALRM, scheduler); + } + ++/* called when we start after a dump */ ++linit_lwp() ++{ ++ FD_ZERO(&fd_rd); ++ FD_ZERO(&fd_wr); ++ FD_ZERO(&fd_ex); ++} ++ + init_lwp() + { pd *temp_pd; + + temp_pd = &main_pd; +- PUSH(temp_pd); ++ /*PUSH(temp_pd);*/ ++ ++ FD_ZERO(&fd_rd); ++ FD_ZERO(&fd_wr); ++ FD_ZERO(&fd_ex); ++ ++ ENQUEUE(temp_pd, running_queue); + + main_thread = alloc_object(t_thread); + main_pd.pd_thread = main_thread; +@@ -935,10 +1492,12 @@ + Swaiting = make_ordinary("WAITING"); + Sstopped = make_ordinary("STOPPED"); + Sdead = make_ordinary("DEAD"); ++ Sblocking = make_ordinary("BLOCKING"); ++ Sdelayed = make_ordinary("DELAYED"); + siSthread_top_level = make_si_ordinary("THREAD-TOP-LEVEL"); + + make_si_function("THREAD-BREAK-IN", siLthread_break_in); +- make_si_function("THREAD-BREAK-QUIT", siLthread_break_quit); ++/* make_si_function("THREAD-BREAK-QUIT", siLthread_break_quit); */ + make_si_function("THREAD-BREAK-RESUME", siLthread_break_resume); + + make_function("MAKE-THREAD", Lmake_thread); +Only in zsrc/c: lwp.my +Only in zsrc/c: lwp.orig +diff --recursive --unified=3 src/c/main.c zsrc/c/main.c +--- src/c/main.c Mon Apr 15 20:54:12 1996 ++++ zsrc/c/main.c Mon Jul 22 18:14:02 1996 +@@ -170,6 +170,11 @@ + setbuf(stdin, stdin_buf); + setbuf(stdout, stdout_buf); + ++#ifdef THREADS ++ fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); ++ fcntl(fileno(stdout), F_SETFL, O_NONBLOCK); ++#endif ++ + ARGC = argc; + ARGV = argv; + ecl_self = argv[0]; +@@ -185,6 +190,7 @@ + gc_time = 0; + + #ifdef THREADS ++ clwp = &main_lpd; + Values = main_lpd.lwp_Values; + #endif + frs_top = frs_org-1; +@@ -226,6 +232,7 @@ + enable_interrupt(); + siLcatch_bad_signals(0); + #ifdef THREADS ++ linit_lwp(); + enable_lwp(); + #endif THREADS + SYM_VAL(siVlisp_maxpages) = MAKE_FIXNUM(real_maxpage); +Only in zsrc/c: main.my +diff --recursive --unified=3 src/c/print.d zsrc/c/print.d +--- src/c/print.d Fri Jul 5 02:41:09 1996 ++++ zsrc/c/print.d Wed Jul 17 16:38:16 1996 +@@ -2258,7 +2258,10 @@ + write_ch_fun = interactive_writec_stream; + else + #endif CLOS ++ { ++ printf("type_of(strm) == %d, t_stream == %d\n", type_of(strm), t_stream); fflush(stdout); + FEerror("~S is not a stream.", 1, strm); ++ } + write_ch('\n', strm); + FLUSH_STREAM(strm); + return(Cnil); +diff --recursive --unified=3 src/c/read.d zsrc/c/read.d +--- src/c/read.d Thu Jun 6 03:50:15 1996 ++++ zsrc/c/read.d Wed Jul 17 02:20:29 1996 +@@ -253,12 +253,30 @@ + + #if TK + extern bool no_input; ++#ifdef THREADS ++# define PUTC(c, fp) lwpputc(c, fp) ++#else ++# define PUTC(c, fp) putc(c, fp) ++#endif + #define GETC(c, fp) { if (fp == stdin) \ + while (no_input) Tk_DoOneEvent(0); \ ++#ifdef THREADS ++ c = lwpgetc(fp); \ ++#else + c = getc(fp); \ ++#endif /* THREADS */ + no_input = !FILE_CNT(fp); } + #else ++#ifdef THREADS ++# define PUTC(c, fp) lwpputc(c, fp) ++#else ++# define PUTC(c, fp) putc(c, fp) ++#endif ++#ifdef THREADS ++#define GETC(c, fp) c = lwpgetc(fp) ++#else + #define GETC(c, fp) c = getc(fp) ++#endif /* THREADS */ + #endif /* TK */ + + /* Beppe: faster code for inner loop from file stream */ +diff --recursive --unified=3 src/c/tcp.c zsrc/c/tcp.c +--- src/c/tcp.c Wed May 31 18:36:36 1995 ++++ zsrc/c/tcp.c Wed Jul 17 21:22:12 1996 +@@ -12,6 +12,7 @@ + */ + + #include "config.h" ++#include + + object + make_stream(object host, int fd, enum smmode smm) +@@ -35,6 +36,9 @@ + stream = alloc_object(t_stream); + stream->sm.sm_mode = (short)smm; + stream->sm.sm_fp = fp; ++#ifdef THREADS ++ fcntl(fd, F_SETFL, O_NONBLOCK); ++#endif + fp->_IO_buf_base = NULL; /* BASEFF */; + stream->sm.sm_object0 = Sstring_char; + stream->sm.sm_object1 = host; /* not really used */ +@@ -67,11 +71,11 @@ + FEerror("~S is a too long file name.", 1, host); + + #ifdef THREADS +- start_critical_section(); ++/* start_critical_section(); */ + #endif THREADS + fd = connect_to_server(host->st.st_self, fix(port)); + #ifdef THREADS +- end_critical_section(); ++/* end_critical_section(); */ + #endif THREADS + + if (fd == 0) { +@@ -94,13 +98,7 @@ + if (!FIXNUMP(port)) + FEwrong_type_argument(TSpositive_number, port); + +-#ifdef THREADS +- start_critical_section(); +-#endif THREADS + fd = create_server_port(fix(port)); +-#ifdef THREADS +- end_critical_section(); +-#endif THREADS + + if (fd == 0) + VALUES(0) = Cnil; +@@ -116,4 +114,190 @@ + { + make_si_function("OPEN-CLIENT-STREAM", Lopen_client_stream); + make_si_function("OPEN-SERVER-STREAM", Lopen_server_stream); ++} ++ ++/* ++ ++ Ok, maybe this shouldn't be here, but it really doesn't belong in ++ crs does it? Also moving it here makes life much easier. ++*/ ++ ++/* socket.c -- socket interface */ ++/* Maybe this shouldn't be here, but what the hell. */ ++/* ++ Copyright (c) 1990, Giuseppe Attardi. ++ ++ ECoLisp is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Library Public License as published ++ by the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ See file '../Copyright' for full details. ++*/ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++extern int errno; ++ ++/*********************************************************************** ++ * Client side ++ **********************************************************************/ ++ ++/* ++ * Attempts to connect to server, given host and port. Returns file ++ * descriptor (network socket) or 0 if connection fails. ++ */ ++int connect_to_server(char *host, int port) ++{ ++ struct sockaddr_in inaddr; /* INET socket address. */ ++ struct sockaddr *addr; /* address to connect to */ ++ struct hostent *host_ptr; ++ int addrlen; /* length of address */ ++ extern char *getenv(); ++ extern struct hostent *gethostbyname(); ++ int fd; /* Network socket */ ++ ++ /* Get the statistics on the specified host. */ ++ if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) { ++ if ((host_ptr = gethostbyname(host)) == NULL) { ++ /* No such host! */ ++ errno = EINVAL; ++ return(0); ++ } ++ /* Check the address type for an internet host. */ ++ if (host_ptr->h_addrtype != AF_INET) { ++ /* Not an Internet host! */ ++ errno = EPROTOTYPE; ++ return(0); ++ } ++ /* Set up the socket data. */ ++ inaddr.sin_family = host_ptr->h_addrtype; ++ memcpy((char *)&inaddr.sin_addr, (char *)host_ptr->h_addr, ++ sizeof(inaddr.sin_addr)); ++ } ++ else ++ inaddr.sin_family = AF_INET; ++ ++ addr = (struct sockaddr *) &inaddr; ++ addrlen = sizeof (struct sockaddr_in); ++ inaddr.sin_port = port; ++ inaddr.sin_port = htons(inaddr.sin_port); ++ /* ++ * Open the network connection. ++ */ ++ if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) ++ return(0); /* errno set by system call. */ ++ ++#ifdef TCP_NODELAY ++ /* make sure to turn off TCP coalescence */ ++ { int mi; ++ setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int)); ++ } ++#endif ++ ++#ifdef THREADS ++start_critical_section(); ++#endif ++ if (connect(fd, addr, addrlen) == -1) { ++ (void) close (fd); ++#ifdef THREADS ++end_critical_section(); ++#endif ++ return(0); /* errno set by system call. */ ++ } ++ /* ++ * Return the id if the connection succeeded. ++ */ ++ return(fd); ++} ++ ++ ++/*********************************************************************** ++ * Server side ++ **********************************************************************/ ++/* ++ * Creates a server port. Returns file ++ * descriptor (network socket) or 0 if connection fails. ++ */ ++ ++int create_server_port(int port) ++{ ++ struct sockaddr_in inaddr; /* INET socket address. */ ++ struct sockaddr *addr; /* address to connect to */ ++ int addrlen; /* length of address */ ++ int request, conn; /* Network socket */ ++ ++ /* ++ * Open the network connection. ++ */ ++ if ((request = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ++ return(0); /* errno set by system call. */ ++ } ++ ++#ifdef SO_REUSEADDR ++ /* Necesary to restart the server without a reboot */ ++ { ++ int one = 1; ++ setsockopt(request, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); ++ } ++#endif /* SO_REUSEADDR */ ++#ifdef TCP_NODELAY ++ /* make sure to turn off TCP coalescence */ ++ { int mi; ++ setsockopt(request, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int)); ++ } ++#endif ++ ++ /* Set up the socket data. */ ++ memset((char *)&inaddr, 0, sizeof(inaddr)); ++ inaddr.sin_family = AF_INET; ++ inaddr.sin_port = htons(port); ++ inaddr.sin_addr.s_addr = htonl(INADDR_ANY); ++ ++ if (bind(request, (struct sockaddr *)&inaddr, sizeof (inaddr))) ++ FEerror("Binding TCP socket", 0); ++ if (listen(request, 1)) ++ FEerror("TCP listening", 0); ++ ++#ifdef THREADS ++ /* Don't make this file-descriptor non-blocking */ ++ /* just block on it before we attempt to accept from it */ ++ /* Think _hard_ about moving this out of here, into somewhere sane */ ++ /* and creating an 'accepting' stream type, which is bound to a port */ ++ /* on reading returns streams */ ++ { ++ FILE *fp; /* need to use FILE *'s rather than fd... *sigh* */ ++ if ((fp = fdopen(request, "r")) == (FILE *)0) { ++ printf("fdopen didn't work on accept fd!\n"); fflush(stdout); ++ } ++ fcntl(request, F_SETFL, O_NONBLOCK); ++ clearerr(fp); ++ ++loop: errno = 0; ++#endif ++ if ((conn = accept(request, (struct sockaddr *)NULL, (int *)NULL)) < 0) ++#ifndef THREADS ++ FEerror("Accepting requests", 0); ++#else /* THREADS */ ++ if (errno) { ++ lwpblockon(active, fp, PD_INPUT); ++ clearerr(fp); ++ goto loop; ++ } else { ++ fclose(fp); ++ FEerror("Accepting requests", 0); ++ } ++ fclose(fp); ++ } ++#endif /* THREADS */ ++ return(conn); + } +diff --recursive --unified=3 src/c/unixint.c zsrc/c/unixint.c +--- src/c/unixint.c Sun Sep 24 01:05:26 1995 ++++ zsrc/c/unixint.c Sun Jul 21 13:26:47 1996 +@@ -38,12 +38,15 @@ + void + sigint() + { ++ /* always reinit on entry, since there is a wee race condition that */ ++ /* might bite unless you have BSD flavour signals... *sigh* */ ++ ++ signal(SIGINT, sigint); + if (!interrupt_enable || interrupt_flag) { + if (!interrupt_enable) { + fprintf(stdout, "\n;;;Interrupt delayed.\n"); fflush(stdout); + interrupt_flag = TRUE; + } +- signal(SIGINT, sigint); + return; + } + if (symbol_value(SVinterrupt_enable) == Cnil) { +@@ -70,9 +73,11 @@ + void + sigint() + { +-#ifdef SYSV ++/*#ifdef SYSV*/ ++ /* shouldn't hurt to reset it on entry... */ + signal(SIGINT, sigint); +-#endif ++/*#endif*/ ++ + if (critical_level > 0) { + scheduler_interrupted = TRUE; + scheduler_interruption = ERROR_INT; +@@ -101,15 +106,17 @@ + signal_catcher(int sig, int code, int scp) + { + char str[64]; ++/* if not bsd... */ ++ signal(sig, signal_catcher); + + if (!interrupt_enable) { + sprintf(str, "signal %d caught (during GC)", sig); + error(str); + } +- else if (sig == SIGSEGV) ++ else if (sig == SIGSEGV) { + FEerror("Segmentation violation.~%\ + Wrong type argument to a compiled function.", 0); +- else { ++ } else { + printf("System error. Trying to recover ...\n"); + fflush(stdout); + FEerror("Signal ~D caught.~%\ +diff --recursive --unified=3 src/c/unixtime.c zsrc/c/unixtime.c +--- src/c/unixtime.c Wed Jul 5 04:12:07 1995 ++++ zsrc/c/unixtime.c Tue Jul 16 19:53:05 1996 +@@ -74,10 +74,18 @@ + Lround(1, z); + z = VALUES(0); + if (FIXNUMP(z)) ++#ifdef THREADS ++ lwpsleep(fix(z)*1000); ++#else + sleep(fix(z)); ++#endif + else + for(;;) ++#ifdef THREADS ++ lwpsleep(1000000); ++#else + sleep(1000); ++#endif + VALUES(0) = Cnil; + RETURN(1); + } +diff --recursive --unified=3 src/crs/Makefile.in zsrc/crs/Makefile.in +--- src/crs/Makefile.in Wed May 31 02:27:00 1995 ++++ zsrc/crs/Makefile.in Wed Jul 17 12:04:30 1996 +@@ -26,7 +26,7 @@ + + # Files + +-OBJS = unexec.o dld.o @SETJMPO@ socket.o ++OBJS = unexec.o dld.o @SETJMPO@ + HFILES = ../h/config.h $(srcdir)/objff.h + + SYSDIR = .. +@@ -39,9 +39,6 @@ + + dld.o: $(srcdir)/@DLD@.c $(HFILES) + $(CC) -c $(CFLAGS) $(srcdir)/@DLD@.c -o $@ +- +-socket.o: $(srcdir)/socket.c +- $(CC) -c $(CFLAGS) $(srcdir)/socket.c -o $@ + + unexec.o: $(srcdir)/@UNEXEC@.c $(HFILES) + $(CC) -c $(CFLAGS) $(srcdir)/@UNEXEC@.c -o $@ +Only in src/crs: socket.c +diff --recursive --unified=3 src/h/external.h zsrc/h/external.h +--- src/h/external.h Tue Mar 12 20:17:12 1996 ++++ zsrc/h/external.h Wed Jul 17 19:25:23 1996 +@@ -279,9 +279,15 @@ + #ifdef THREADS + extern lpd main_lpd; + extern lpd *clwp; +-extern pd *running_head; +-extern pd *running_tail; + extern pd main_pd; ++extern pd *active; /* active pd */ ++extern pd *running_queue; /* running pd's */ ++extern pd *blocking_queue; /* blocking pd's */ ++extern pd *delayed_queue; /* delaying pd's */ ++extern pd *dead_queue; /* dead pd's */ ++extern pd *stopped_queue; /* stopped pd's */ ++extern pd *suspended_queue; /* suspended pd's */ ++extern pd *waiting_queue; /* waiting pd's */ + #endif THREADS + + /* macros.c */ +diff --recursive --unified=3 src/h/lwp.h zsrc/h/lwp.h +--- src/h/lwp.h Tue Feb 6 04:00:30 1996 ++++ zsrc/h/lwp.h Sat Jul 20 16:44:15 1996 +@@ -146,8 +146,8 @@ + object lwp_gentemp_prefix; + object lwp_token; /* They have to be initialized with + * alloc_simple_string and */ +-} lpd; + ++} lpd; + + #define RUNNING 0 + #define SUSPENDED 1 +@@ -155,6 +155,7 @@ + #define DEAD 3 + #define WAITING 4 + #define DELAYED 5 ++#define BLOCKED 6 + + typedef struct pd { + object pd_thread; /* point back to its thread */ +@@ -166,14 +167,46 @@ + sigjmp_buf pd_env; /* Stack Environment */ + #endif VAX + int pd_slice; /* time out */ ++ int pd_fp_mode; /* in, out, execpt */ + FILE *pd_fp; /* File pointer waiting input on */ + lpd *pd_lpd; /* lisp process descriptor */ + struct pd *pd_next; + + } pd; + ++#define PD_INPUT 0 ++#define PD_OUTPUT 1 ++#define PD_EXCEPTION 2 ++ ++#define ENQUEUE(lpd, queue) \ ++ { if (queue == NULL) { \ ++ lpd->pd_next = lpd; \ ++ queue = lpd; \ ++ } else { \ ++ lpd->pd_next = queue->pd_next; \ ++ queue->pd_next = lpd; \ ++ } } ++ ++#define DEQUEUE(lpd, queue) \ ++ { pd *TMP; \ ++ TMP = queue; \ ++ do { \ ++ if (TMP->pd_next == lpd) { \ ++ TMP->pd_next = lpd->pd_next; \ ++ lpd->pd_next = lpd; \ ++ if (lpd == queue) \ ++ queue = TMP; \ ++ break; \ ++ } \ ++ TMP = TMP->pd_next; \ ++ } while(TMP != queue); \ ++ if (lpd == queue) queue = NULL; \ ++ } + ++#define ROTQUEUE(queue) \ ++ if (queue != NULL) queue = queue->pd_next + ++/* + #define PUSH(lpd) { if ( running_head == NULL) \ + { running_head = lpd; \ + running_tail = lpd; \ +@@ -194,7 +227,7 @@ + running_head = running_head->pd_next; \ + running_tail = running_tail->pd_next; \ + running_tail->pd_next = NULL; } +- ++*/ + + /* + #define PUSH(lpd) ( running_head == NULL \ +Only in zsrc/h: lwp.orig +diff --recursive --unified=3 src/h/machines.h zsrc/h/machines.h +--- src/h/machines.h Thu Jul 4 21:14:03 1996 ++++ zsrc/h/machines.h Mon Jul 15 22:01:57 1996 +@@ -209,7 +209,7 @@ + #define IEEEFLOAT + #define DOWN_STACK + #define BSD +-# if __GNUC__ > 2 || __GNUC_MINOR__ > 6 ++# if 0 /*__GNUC__ > 2 || __GNUC_MINOR__ > 6*/ + # define ELF + # define UNEXEC unexelf + #define DATA_START ELF_TEXT_BASE +Only in zsrc: newthread.tgz +Only in zsrc: socket.c diff --git a/site.lsp b/site.lsp new file mode 100644 index 000000000..4d142a289 --- /dev/null +++ b/site.lsp @@ -0,0 +1,4 @@ +;; Edit these with the name of your site: +;; +(defun short-site-name () "SHORT-SITE-NAME") +(defun long-site-name () "LONG-SITE-NAME") diff --git a/src/CHANGELOG b/src/CHANGELOG new file mode 100644 index 000000000..9298cca6e --- /dev/null +++ b/src/CHANGELOG @@ -0,0 +1,697 @@ +ECL-Spain v0.0 +============== + +* Removed all "break" from the configure script. + +* Added latexinfo.sty to help producing the manual. + +* src/configure.in: profile feature disable by default. + +* Conversion to ANSI prototypes of all files in the library (c/) + directory. Two headers, external.h and lisp_external.h, to keep the + prototypes of C and LISP functions. + +* Fixed lack of "extern" declaration for {short,long}float_zero and + lack of implementation. + +* Fixed lack of "extern" declaration of r frame_stack, frs_limit and + frs_top. Actual implementation added in main.c. + +* Fixed lack of "extern" declaration for Values in the THREADS case, + in vs.h + +* Removed OFLAG as the standard is using CFLAGS + +* Added test tree from CLISP + +* Removed 'break's from configure. + +* Grouped all keyword definitions in a single pool in the new file + all_keywords.c + +* Grouped all symbol definitions in a single pool in the new file + all_symbols.c + +* Removed all calls to register_root() for symbols from the + library. Instead the garbage collector uses the symbol/keyword + definition pools to mark these objects. + +* parse_number() failed when GC was triggered. The reason was that + GC did only reallocate num.size limbs when it should actually move + num.alloc limbs. This has been solved in three steps + + The GC uses num.alloc (= big_dim) + + The allocator clears the bignum + + The bignum data is only relocated when the pointer is valid, + that is, we assume that big_limbs may point to non + collectable memory. + +* The allocator empties a region before returning it. + +* All big_*() functions now get lisp objects as input, in order to + make the interface more abstract. + +* Added #'nth-value + +* Now big_alloc(), alloc_contblock() and alloc_relblock() fail when + passed a negative argument. + +* Created a pool of three bignum registers. These registers may be + used to save consing, as the destination of mpz_* operations, as + follows + + Perform a big_register?_get() + + Perform elementary operations from the GMP library + + Either discard the object, use big_register_copy() or use + big_register_normalize(). + +* Removed most preallocations of bignums, favoring the use of bignum + registers. + +* In integer_quotient_remainder, if both operands are bignums and the + divisor is larger, a bignum with negative size was allocated. The + use of bignum registers fixes this problem. + +* In parse_number() and parse_integer(), use the bignum registers to + store the intermediate result. + +* Implementation of a new stream mode, smm_closed. + +* Fresh streams from alloc_object() are smm_closed streams. + +* In file.d: 1) input_stream_p, output_stream_p, stream_element_type, + readc_stream, unreadc_stream, writec_stream, flush_stream, + clear_input_stream, clear_output_stream, stream_at_end, + listen_stream, file_position, file_position_set, file_length, + file_column fail on closed streams. 2) close_stream and + Lopen_stream_p work on closed streams. + +* In read.d, print.d: Lread_bytes and Lwrite_bytes which could have + tried to access a closed stream. Not a good fix, anyway. + +* array.tst, hashlong.tst, eval20.tst, iofkts.tst, lists152.tst: added #+ECL. + +* In pathname.d: coerce_to_pathname makes sense on closed streams. + +* In print.d: print() did not output a trailing space. + +* In read.d: #'read-char-no-hang now handles EOF and fails or returns + eof-value when appropiate. + +* In format.c: Lformat formerly output a string for non-nil first + argument. + +* In symbols.c, all_symbols.c, lisp_externals.h: implemented + *gensym-counter* + +* In symbols.tst: placed (setq *gensym-counter*...) right before + creating the symbol --otherwise a spurious gensym is produced by the + interpreter. + +* predlib.lsp: errata in subtypep caused failure for '(not ....) and + '(and ...) types. + +* predlib.lsp: #'normalized-type now turns (integer a (b)) into + `(integer a ,(1- b)), producing an output which is suitable for + sub-interval-p. + +* predlib.lsp: #'typep now rejects type specifiers that it doesn't + know about. For instance, '(symbol cons) is rejected. + +* predlib.lsp: #'typep on '(MEMBER ...) now only outputs T or NIL. + +* strings.tst: added #+ECL and now included in the test-suite. + +* string.d: member_char() hangs when the character bag has some + non-character objects. + +* string.d: nstring-{up,down}case now reject NIL as bound designator + when compiled in ANSI compatibility mode. + +* characters.tst: added #+ECL and included in the test-suite. + +* pack11.tst: the keyword :use from #'in-package needs a list, no + a single symbol. Added to the test. + +* package.d: packages must be case sensitive. This implies changes in + find_package() + +* package.d: #'package-name should also accept symbols and strings. + +* package.d: #'unexport should ignore internal symbols. + +* Makefile.in: makes tar file. + +* in system.lsp: new syntax for defsystem, takes care of multiple + source directories and separate path for library. + +* in {lsp,cmp,clos}/defsys.lsp.in: modified with new syntax. + +* in load.d: build_symbol_table is now a C function invoked from the + initialization code and not exported to lisp. + +* in cmpmain.lsp: new #'build-ecl function to build customized + executables. It generates the initialization code. + + +ECL v0.0b +========= + +* in lsp/predlib.lsp: extended #'typep to classes. + +* in cmp/cmpdefs.lsp: added types for all compiler structures. + +* in clos/standard.lsp: redefine-class should be evaluated at compile + time. + +* in clos/: fixed everything to allow generation of *.c files. + +* in lsp/predlib.lsp: subclassp now exported from LISP package. + +* in c/pathname.d: + + now pathnames are constructed according to ANSI. We support + :ABSOLUTE, :RELATIVE, :UP and :WILD, and we require their use when + constructing pathnames. + + All pathnames are considered relative except those which begin + with '/' or '~/'. The last case is expanded using the $HOME + environment variable. + + pathnames are merged according to ANSI CL. If 'pathname' is a + relative directory, it is merged with 'default's directory, no + matter whether this one is relative or not. + + tilde_expand() hidden as static -- it is far too low level. + + current_dir() and getcwd() substitutes all uses of getwd(). + + fixed size buffers removed from most routines to avoid accidental + overflows. Use of current_dir() and siLstring_concatenate() prevents + this type of errors. + +* in c/unixfsys.c: + + truename() rewritten to detect only files and signal errors when + it finds directories. + + Ltruename() now returns the number of output values. + + Lrename_file() now outputs true names by checking the renamed file + after the operation. + + string_match() and siLstring_match() provide SH-like patterns. + + Ldirectory() only lists files and allows all wildcards that + siLstring_match() provides. The implementation dependent keyword, + :LIST-ALL, instructs Ldirectory() to list both files, directories + and special nodes such as devices, pipes, etc. + +* in c/read.d: + + Added Lsharp_P_reader() to read paths using #P. + + Ldefault_dispatch_macro() outputs clearer error message. + +* in lsp/defstruct.lsp,lsp/iolib.lsp: sharp-s-reader and + sharp-s-reader-si now ignore data when *read-suppress*. + +* in lsp/module.lsp: #"" replaced with #P"". + +* in c/lwp.d,c/big.c: per-thread allocation bignum registers. + +* in c/Makefile.in,gmp/Makefile.in: make use of './' to avoid the need + of exporting PATH with a '.' inside. + +* in c/print.d: Now paths are printed as #P. + +* in Makefile.in: BUILDIR mispelled caused failure of installation. + +ECLS v0.0c +========== + +* in src/configure.in: make using CLOS the default. + +* in gmp/Makefile.in,gmp/mpz/Makefile.in: fixed recursive error in + cleaning. + +* in lsp/iolib.lsp,lsp/packlib.lsp: removed use of ". body" favoring + the use of "&rest body" because sys::expand-defmacro doesn't + understand it. + +* in c/gbc.c: added gc marking of objects in lexical envs. + +* in c/macros.c: define-macro now uses default values for last two + arguments when they are missing. + +* in c/clos.c,c/package.d,c/print.d,c/read.d: added register_root() to + some variables. + +* in lsp/builtin.lsp: removed make-instance on structure-metaclass, + since it does not exist. + +* in lsp/predlib.lsp: + + implemented sequence as a deftype + + removed sequence from subtypep + + built normalize-type to return multiple values + + recoded subtypep & coerce to use multiple values from normalize-type + + when using clos, deftype structure as STRUCTURE-OBJECT + +* in c/let.c: save values in Fmultiple_value_bind before performing + the actual let_bind. This prevents losing data within a GC. + +* Now a raw ecl_min file is built which uses no lisp compiled files, + to provide a tool for bootstraping ECL. This implies some changes + to avoid circular dependencies + + src/c/Makefile.in creates an init_min.o when bootstraping + + src/Makefile.in uses init_min.o,c/*.o and crs/*.o to create the + raw ECL which we will use to bootstrap. + + c/init.c now loads *.lsp files when bootstraping + + lsp/defmacro.lsp postpones definition of defmacro until + sys::expand-defmacro is defined + + lsp/defmacro.lsp does not use 'defvar because it is not defined. + + lsp/iolib.lsp,lsp/module.lsp,lsp/packlib.lsp now use &optional + instead of . in macros, as defmacro does not support '.' + + clos/method.lsp: when :ecl-min, replace *safe-compile* with t + + cmp/load.lsp: replace call to object-type with its result. + + new src/config_min.lsp which performs booting. + +* in cmp/cmpinline.lsp: inline-args adds a bogus arg when inlining + instance-ref. This problem only arised when *safe-compile*. + +* in lsp/defmacro.lsp: + + #'sys::destructure handles destructuring lambda lists + + #'defmacro reimplemented using #'sys::destructure, which now + handles '.' arguments properly. + + new #'destructuring-bind implemented using #'sys::destructure + +* in c/unixfsys.c: sys::chdir now outputs original directory. + +* in h/: lisp_external.h and unify.h were missing from CVS. + in c/: all_symbols.c and all_keywords.c were missing from CVS. + in contrib: ilisp removed, there are better versions around. + +* new src/compile.lsp.in, lsp/defsys.lsp.in, clos/defsys.lsp.in, + cmp/defsys.lsp.in, plus changes in src/config.lsp.in, + src/configure.in and src/Makefile.in: now the C files are + compiled on-the fly usin the bare feet ecl_min program. + +ECLS v0.0d +========== + +* in clos/generic.lsp: implemented :method in #'defgeneric + +* in lsp/predlib.lsp: extended #'typep to classes and made #'subclassp + public. + +* New codeblock object which keeps all information about an object + file and its data. It replaces the old tagless structure and + introduces a new format for init_*() function when initializing an + object file. + +* Moved compiler data into object files as C string. This implies + changes in the loader (load.d), in the data stream reader + (read_VV) and in the compiler (cmpwt.lsp,cmpmain.lsp,cmptop.lsp) + which nows generates a different boot code for compiled lisp files. + +* in cmp/cmpmain.lsp: new #'make-library joins several object files + into an *.a file, adding a new object file which initializes them + all and exports an init_*() routine. + +* cmp/cmpmain.lsp: compiler-pass2 now upcases init_* names to avoid + name clashes with lisp code. + +* in src/util/system.lsp: new :LIBRARY target which uses + compiler::make-library to produce *.a libraries up from CLOS, LSP + and CMP subdirectories. + +* in src/c/Makefile.in: now a library libecls.a is built up from + all object files except cinit*.o + +* in src/Makefile.in, src/compile.lsp: ecl_min is built up only from + the core C library, while ecl is built with this core and all + required libraries liblsp.a, libcmp.a, libclos.a, etc, plus + config.o. To help in this compile.lsp is used to build all required + libraries. + +* load.d: siLbuild_symbol_table no longer removes ecl.sym + +* in c/main.c,c/cinit.c,c/load.d: removed system_directory C variable. + The lisp variable *system-directory* is used instead and points to + the system files (headers, libraries, initialization code). Default + value for this one is assigned during the configuration phase and + defaults to @libdir@ + +* in cmp/cmpmain.lsp: header is no longer copied onto the + compiled code, but #inlined from the system directory. + +* in c/package.d, c/assignment.c, c/macros.c, c/toplevel.c, + h/object.h: new function #'sys::package-lock locks a package and + subsequents redefefinitions of functions/macros produce a warning. + +* config.lsp moved to lsp/config.lsp and compiled into interpreter. + +* in Makefile.in, src/Makefile.in: primitive installation method, + which stores $(bindir)/ecl, $(mandir)/man.1, $(libdir)/ecl.sym, + $(libdir)/help.doc and $(libdir)/h/ecl.h + +ECLS v0.0e +========== + +* Support for FreeBSD >= 4.0 using ELF. + +* Defined ANSI and #+ansi by default, except in number_atan(), which + needs fixing. + +* in package.d: lisp package renamed to common-lisp with nicknames + "lisp" and "cl", and user package renamed to common-lisp-user with + nicknames "cl-user" and "user". + +* in export.d: common-lisp-user, cl, cl-user, common-lisp added to + export list of common-lisp package. + +* in defsys.lsp: ansi.lsp, loop.lsp and defpackage.lsp incorporated. + +* in package.d: shadow did not shadow already interned objects. + +* in toplevel.c: added :execute, :compile-toplevel and :load-toplevel + to eval-when. + +* in list.d: fixed #'last adding optional argument + +* in src/util/system.lsp: new syntax which allows separate directory + for library. + +* src/config.lsp.in moved to src/lsp/config.lsp.in and incorporated + into liblsp.a + +* in cmp/cmpmain.lsp: new #'build-ecl to build customized executables. + {lsp,cmp,clos}/defsys.lsp.in updated accordingly. + +* in src/Makefile.in: new build process relying entirely on lisp and + defsystem to build executables. + +* in print.d: when *print-escape* is nil, pathnames are written as + addresses -- now the namestring is output. + +* in predicate.c: functionp = 't on symbols bound to functions. + +* in src/Makefile.in: strip executables. + +* in lsp/seq.lsp: #'make-sequence was broken due to new #'normalize-type. + +* in lsp/predlib.lsp: #'coerce was broken due to new #'normalize-type. + Plus a quick hack to handle 'LIST properly. + +* in cmp/cmpmain.lsp: #'build-ecl now also strips symbols using + "rsym", which gets installed into @libdir@ + +* Simplified the set of headers. Now there is a ecls.h for base code + and ecls-cmp.h for lisp compiled code, both sharing the rest of + headers (stacks.h, object.h, etc), to simplify maintenance. + +ECLS v0.0g +========== + +* Binding stack, invocation history stack and frame stack predate now + ordinary memory as a first step for future resizable stacks. + +* Built in C strings are better handled now: they can contain \000 and + make use of \n,\t,\\, and of special characters in octal notation. + +* Final problems with documentation solved. #'si::help no longer hangs + and the database is now properly generated (in v0.0e only a few + entries got in). + +* New online manual in texinfo format gets installed. + +* Support for character attributes removed, including #'char-bit, + #'char-font, #'make-character, #'string-char-p and 'string-char + type. Instead, the whole chapter of the ANSI spec is implemented + with types character = base-char > standard-char and extended-char + being an empty type. + +* Initialization of functions grouped in a single file all_functions.c. + +* Full ANSI compliance for CHARACTER and STRING sections of the spec. + +* (type-of nil) now returns 'NULL instead of 'SYMBOL. + +* Different hierarchy of tags in object.h saves some space & time. + +* Open-coded caar, cadr, etc, are faster & smaller. + +* In old garbage collector, flag *IGNORE-MAXIMUM-PAGES* turned into + function #'si:ignore-maximum-pages + +* Added support for Boehm-Weiser garbage collector with flag + --enable-boehm. + +* Removed support for relocatable blocks of memory from original + garbage collector. Unified allocation interface with alloc(), + alloc_align(), dealloc() and the alloc_atomic() and + alloc_atomic_align() variants. + +ECLS v0.0h +========== + +* big_bitp() was broken due to the use of wrong limb sizes. Furthermore, + it did not consider the case of negative bignums. + +* gmp-3.1 takes the place of the original gmp-1. + +* Now it is possible to link ECLS with a local copy of the GMP library, + avoiding to compile and install the copy that comes with it. + +* New C functions floor1, floor2, ceiling1, ceiling2, truncate1, + truncate2, round1, round2 which correspond to #'floor, #'ceiling, + #'truncate and #'round with one or two arguments, but which are only + used internally. Lfloor, Lceiling and Ltruncate implemented using + them. + +* Rewritten many routines optimizing and removing or completing type + checks. For instance, make_complex(), + number_{plus,minus,times,divide}(), integer_divide(), log_op(), etc. + +* At cost of some speed, the interpreter (i.e. not compiled code) + keeps track of all called functions for better error signaling. + +* Some failed type checks are now restartable in most cases in which + it is safe. This allows the user to dynamically supply a different + value + > (make-list 'a :initial-element 'b) + Correctable error: A is not of type (INTEGER 0 *). + Signalled by MAKE-LIST. + If continued: Enter new value. + ;;; Warning: Clearing input from *debug-io* + Broken at MAKE-LIST. + >> :b + Backtrace: > MAKE-LIST + >> :continue + Enter new value> 10 + (B B B B B B B B B B) + > + The jump to the debugger may be suppressed by binding *break-enable* + to nil. + > (setq *break-enable* nil) + NIL + > (make-list 'a :initial-element 'b) + Correctable error: A is not of type (INTEGER 0 *). + Signalled by MAKE-LIST. + Aborting: + > + +* Support for logical pathnames. The syntax for logical pathnames is + [hostname:][;][directory-item;][name][.type] + and the syntax for physical pathnames is extended to + [device:][[//hostname]/][directory-item/][name][.type] + where device defaults to "file". Pathname translation and matching + is also implemented, although wildcard expansion is not maximal + and works more like "sh" than like "regexp". + +* New set of C types which includes: cl_object for all lisp objects, + cl_fixnum for an integer large enough to hold a fixnum, cl_index for + an unsigned integer large enough to index an array, cl_hashkey for + hashing and cl_type for all type tags. + +* New macros LISTP(), ATOM(), CONSP(), SYMBOLP() optimize type checks + within the library code and within automatically generated C + compiled code. + +* Errors fixed: + + Removed non-standard keyword argument :staticp from #'make-array + and #'make-vector. + + A fixnum is no longer a valid string designator. + + #'butlast and #'nbutlast now work with dotted lists. + + Inlined #'tan now produces the right code. + + A fixnum cannot be coerced to a character. + + Character bags of type vector would produce erroneous results. + + #'equalp would fail to compare complex numbers + + #'char now only accepts strings + + in pathnames, namestrings, etc, symbols are not implicitely + coerced to strings. + +* The Common-Lisp reader has been reworked to allow an unlimited + number of #= and ## references in circular structures. Besides, this + also fixes the accidental deactivation of the #=/## readers in ECLS + v0.0g :( + +* Errors detected but not yet fixed throught all bit manipulating + functions: they fail to fake two's complement convention for + negative bignums. + +* Big change of names in structure members: ht.ht_size -> hash.size, + etc. Less redundant and more expressive. + +* Packages are now stored in a list. The link in the package object + has been removed. We make sure this list is garbage collected by + applying "register_root()" on it. Garbage collection of package + objects is now moved into the mark_object() routine. + +ECLS 0.0i +========= + +* Replaced hashing function with a crc32. + +* Packages now use standard hashes for storing symbols. This seems + to reduce the amount of wasted memory at now speed cost. Besides, + future improvements to hashes will get in packages as well. + +* The interpreter is now capable of passing the whole suite of tests. + Just issue "make ecls_min_test" from within build/test directory. + +* Errors can be ignored by setting si:*ignore-errors* to true. If this + happens, a (throw si:*ignore-errors-tag* 'ERROR) is thrown. Hence + a useful construct for testing is + (defmacro with-ignored-errors (&rest forms) + `(catch si::*ignore-errors-tag* + (let ((si::*ignore-errors* t)) ,@forms))) + +* Improvements to the "dpp" preprocessor that generates code for the + core library: + + All C code is now run by the preprocessor. + + Simplified #line staments in the output make files more readable. + + It now exits with value != 0 when errors occurr, which means + makefiles now stop when the *.d file has errors. + + It accepts more flexible input as tokens. No need of [`] character, + use parenthesis instead; function names may contain packages + as in "si::unwind" + + It does not generate #define/#undefine pragma, but uses variables + instead. + +* Errors fixed: + + #'mapcan and #'mapcon failed to handle dotted lists. + + Inlined short-float/long-float values were truncated to ints. + + declaim's effects are now visible at compile time. + + proclaim causes no effect at compile time. + + declarations cannot arise as the result of a macro expansion. + +* CL package unpolluted: + + 'system, '*break-enable* and others now rest in the 'system package. + + function #'proclamation removed + +* New macro expanders help the compiler to produce the right code for + (do ((s "asbc") c (i 0 (1+ i))) + ((= i 3) c) + (declare (type character c)) + (setq c (char s i))) + Formerly, C would be initialized with "char_code(Cnil)" which is + probably not what the user wanted. + +* IN-PACKAGE is now a macro and DEFPACKAGE now expands to a shorter + expression with the help of an internal function SI:%DEFPACKAGE. + +* Evaluation of (LAMBDA (..) ...) expressions now conses less when in + an empty lexical environment. + +* The system now uses a different protocol for returning values. + + If a lisp function returns one single value, the C function + outputs that value directly and sets NValues=1. + + If N values are output, the function, sets NValues=N; it sets + VALUES(1..N-1) to the N-1 last values and outputs the first one. + +* The code walker in PCL now avoids macroexpanding DOTIMES, DOLIST, + WHEN and UNLESS. This gives smaller/faster code in the interpreter. + +ECLS 0.1a +========= + +* Brand new interpreter based on a byte compiler. This implies major + changes to CLOS, the code walker and to the compiler. + +* Export COMPILE-FILE-PATHNAME. + +* Gabriel's benchmark incorporated to the source tree. + +* Ported to NetBSD. + +* Added support for SYMBOL-MACROLET in the interpreter. + +* New lisp object for loaded binary files. This helps in garbage + collection of FASL objects and serves as a base for DLL support. + +* Fixed documentation and doc/help.lsp. + +* Fixed benchmark, which now output results in right order. + +* SETF revised. Now it, and all accessors are implemented as macros + with no special support from the interpreter. + +ECLS 0.1b +========= + +* Due to human errors, the bytecompiler shipped with 0.1a was not the + finished version. In 0.1b we shipped a more polished files. Some of + the errors which are fixed are + + Produce the right code for TAGBODY inside closures + + Activate compiler for SYMBOL-MACROLET + + Allow non-keyword symbols as lambda-list-keywords + + Allow more than one :ALLOW-OTHER-KEYS to be supplied, but + discard other than the first one + + Process declarations in FLET/LABELS forms + +* Fixed the C compiler routines for TAGBODY: it would produce wrong + code when jumping out of a closure. + +* Rewrite the error system using KMP's condition system, CLOS and a + rudimentary interface to the toplevel. + +* Enclosing the bytecompiler in an UNWIND-PROTECT ensures that the + status of the compiler and of the interpreter is always consistent. + +* Port and incorporate Peter Van Eynde's test suite for ANSI + compliance. + +* Replace features ECL/ECL-MIN with ECLS and ECLS-MIN. + +* Add simple-program-error and simple-control-error to the hierarchy + of conditions, and try to ensure that all routines in libecls.a + signal the right type of condition. + +* Define COMPLEMENT and CONTINOUSLY. + +* Fix #'= between bignums. + +* NIL is no longer valid as the first of a pair of bounding index + designators, i.e. (nstring-upcase "aa" :start nil :end nil) causes + an error. + + +TODO: +===== + +* Selectively remove spices from read.d and object.h + +* Implement memory collection based on mmap() + +* Improve the garbage collector using kernel information about dirty + pages. + +* Improve fixnum_times. + +* #'unread-char does not fail when the character differs from the + original one. + +* vector-push-extend may succeed even if the vector is not + adjustable. Should we be more strict? + +* should we relax ASSOC? (See lists156.tst) + +* boost setf and generalized places -- the current implementation is + extremely faulty with respect to the standards. + +* expand parse_namestring() to accept scaped strings, spaces, etc. + +* fix FEerror* so that it accepts parameters. + +* Remove most property lists from standard symbols. + +;;; Local Variables: *** +;;; mode:text *** +;;; fill-column:70 *** +;;; End: *** diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 000000000..bedb4a64b --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,169 @@ +# +# Makefile for ECoLisp +# +top_srcdir= @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +MACHINE = @MACHINE@ + +# Programs used by "make": +# + +CC = @CC@ +DEFS = -D$(MACHINE) +LIBS = @LIBS@ @TKLIBS@ @CLIBS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ + +#ifdef __GO32__ +EXE = go32 +#elif defined(__EMX__) +EXE = emx +#else +EXE = +#endif + +SHELL = /bin/sh +RM = @RM@ + +# ==================== Where To Install Things ==================== + +# The default location for installation. Everything is placed in +# subdirectories of this directory. The default values for many of +# the variables below are expressed in terms of this one, so you may +# not need to change them. This defaults to /usr/local. +bindir=@bindir@ +libdir=@libdir@ +mandir=@mandir@ +manext=.1 +infodir=@infodir@ + +# Programs used by "make install": +# +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +# Files + +SUBDIR = c gmp crs +LIBRARIES = libecls.a libcrs.a +TARGETS = ecls +#ifndef HAVE_LOCAL_GMP +LIBRARIES += libgmp.a +#endif +#ifdef GBC_BOEHM +SUBDIR += gc +LIBRARIES += libgc.a +#endif GBC_BOEHM +LSP_LIBRARIES = liblsp.a +#ifdef CLOS +LSP_LIBRARIES += libclos.a +#endif +#ifndef RUNTIME +LSP_LIBRARIES += libcmp.a +#endif +#ifdef CLX +TARGETS += eclx +LSP_LIBRARIES += libclx.a +#endif + +# The makefiles of the directories in $SUBDIR. +# Don't split this line: configure does grep on it +SUBDIR_MAKEFILES= c/Makefile crs/Makefile tk/Makefile doc/Makefile gc/Makefile + +all: $(TARGETS) doc +.PHONY: all + +%Makefile: $(srcdir)/%Makefile.in config.status + ./config.status + +eclx: ecls compile_rest.lsp + ./ecls < compile_rest.lsp + +ecls: ecls_min compile.lsp + ./ecls_min < compile.lsp + +ecls_min: $(LIBRARIES) @RSYM@ .gdbinit + $(CC) $(LDFLAGS) -o $@ c/cinit.o -L./ $(LIBRARIES) $(LIBS) + test "@RSYM@" = "" || ./rsym ecls_min ecls_min.sym + +.gdbinit: $(srcdir)/util/gdbinit + cp $(srcdir)/util/gdbinit $@ + +libecls.a: + cd c; $(MAKE) +libgc.a: + cd gc; $(MAKE) +libcrs.a @RSYM@: + cd crs; $(MAKE) + test "@RSYM@" = "" || cp crs/@RSYM@ . +libgmp.a: + cd gmp; $(MAKE); cp .libs/libgmp.a .. + +BUILD-STAMP: config.status + (echo "#"; uname -a) > $@ + head -8 config.status | tail -6 >> $@ +install: BUILD-STAMP + for i in $(TARGETS); do $(INSTALL_PROGRAM) $$i $(PREFIX)$(bindir); strip $(PREFIX)$(bindir)/$$i; done + $(INSTALL_DATA) $(srcdir)/etc/ecls.1 $(PREFIX)$(mandir) + test -d $(PREFIX)$(libdir) || (mkdir $(PREFIX)$(libdir); chmod 755 $(PREFIX)$(libdir)) + test -d $(PREFIX)$(libdir)/h || (mkdir $(PREFIX)$(libdir)/h; chmod 755 $(PREFIX)$(libdir)/h) + for i in $(TARGETS); do $(INSTALL_PROGRAM) $$i.sym $(PREFIX)$(libdir); done + $(INSTALL_DATA) BUILD-STAMP $(PREFIX)$(libdir) + $(INSTALL_DATA) h/config.h $(PREFIX)$(libdir)/h +#ifndef HAVE_LOCAL_GMP + $(INSTALL_DATA) gmp/?*.h $(PREFIX)$(libdir)/h + $(INSTALL_DATA) $(srcdir)/gmp/?*.h $(PREFIX)$(libdir)/h +#endif + for i in $(LSP_LIBRARIES) $(LIBRARIES); do \ + $(INSTALL_DATA) $$i $(PREFIX)$(libdir); \ + done +#ifdef GBC_BOEHM + for i in $(srcdir)/gc/include/?*.h; do $(INSTALL_DATA) $$i $(PREFIX)$(libdir)/h/`basename $$i`; done + test -d $(PREFIX)$(libdir)/h/private || (mkdir $(PREFIX)$(libdir)/h/private; chmod 755 $(PREFIX)$(libdir)/h/private) + for i in $(srcdir)/gc/include/private/?*.h; do $(INSTALL_DATA) $$i $(PREFIX)$(libdir)/h/private/`basename $$i`; done +#endif GBC_BOEHM + test "@RSYM@" = "" || $(INSTALL_PROGRAM) @RSYM@ $(PREFIX)$(libdir) + cd c; $(MAKE) PREFIX="$(PREFIX)" install + cd doc; $(MAKE) PREFIX="$(PREFIX)" install + +uninstall: + rm -rf $(mandir)/ecls.1 + rm -rf $(bindir)/ecls + rm -rf $(libdir) + cd doc; $(MAKE) uninstall + +doc: $(TARGETS) + cd doc; $(MAKE) + +clean: clean_lisp + for i in ${SUBDIR}; do (cd $$i; make clean); done + $(RM) ecls_min ecls_min.sym ecls ecls.sym help.doc core a.out + $(RM) config.version config.log config.cache + $(RM) *.c *.o *.a *.h *.data +clean_lisp: + for i in lsp cmp clos clx tk; do rm -f lib$$i.a $$i/?*.o $$i/?*.c $$i/?*.data $$i/?*.h; done +distclean: clean +realclean: distclean +test1: + cd c; make + make ecls_min + make ecls + cd tests; make + diff tests tests2 +test2: + make clean_lisp + cd c; make + make ecls_min + $(RM) ecls + make ecls + for i in lsp clos cmp; do diff --exclude=\*.o $$i old/$$i; done +test3: + -mkdir stage2 + cp -rf lsp clos cmp stage2 + -for i in lsp cmp clos clx tk; do test -f lib$$i.a && mv lib$$i.a stage2; done + make clean_lisp + ./ecls < compile2.lsp + for i in lsp clos cmp clx tk; do test -d $$i && diff --exclude=\*.o $$i stage2/$$i; done \ No newline at end of file diff --git a/src/ansi-tests/GNU-GPL b/src/ansi-tests/GNU-GPL new file mode 100644 index 000000000..39b03e9a2 --- /dev/null +++ b/src/ansi-tests/GNU-GPL @@ -0,0 +1,340 @@ + 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 + + Appendix: 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. + + + Copyright (C) 19yy + + 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. + + , 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/src/ansi-tests/Makefile.in b/src/ansi-tests/Makefile.in new file mode 100644 index 000000000..f20d3cb36 --- /dev/null +++ b/src/ansi-tests/Makefile.in @@ -0,0 +1,29 @@ +top_srcdir=@top_srcdir@ +srcdir=@srcdir@ + +RM=rm -fr +MV=mv -f +MKDIR=mkdir -p + +.PHONY: clisp sbcl normal safe ecls ecls_min + +ecls: + ln -sf ../../src/h/*.h ../h/ + (echo '(load "$(srcdir)/tests")'; \ + echo '(setq si::*system-directory* "../")'; \ + echo "(run-all-tests \"$(srcdir)/\")"; \ + echo "(quit)") | ../ecls + true + +ecls_min: + ln -sf ../../src/h/*.h ../h/ + (echo '(load "bare.lsp")'; \ + echo '(setq si::*system-directory* "../")'; \ + echo '(sys::chdir "ansi-tests")'; \ + echo '(load "$(srcdir)/tests")'; \ + echo "(run-all-tests \"$(srcdir)/\")"; \ + echo "(quit)") | (cd ..; ./ecls_min) + true + +clean: + $(RM) *.erg *.o *.c *.h *.data \ No newline at end of file diff --git a/src/ansi-tests/README b/src/ansi-tests/README new file mode 100644 index 000000000..89bd64e90 --- /dev/null +++ b/src/ansi-tests/README @@ -0,0 +1,28 @@ +This is a bunch of tests to test if a Common Lisp implementation +conforms to Ansi standard X3J13 for Common Lisp. + +It is largely based on the clisp test-suite, examples from the HyperSpec and +bugreports. + +This is a work in progress. + +Even though it's in the clocc package, the ansi-tests system +is a standalone system. It can run without having anything else +from clocc available; all you need is the ansi-test/ directory. + +There is a Makefile that should sort-of-work, please look at it +and adapt it to your situation. + +To run the tests manually, start your Lisp in the ansi-test/ +directory and type +(load "tests.lisp") +at the command prompt. + +The tests produce output on the console, with failed tests +marked with "ERROR!!". They also produce error output files +with extensions ".erg", where every entry in such a file +is from a failed test. Thus, if ansi-test thinks your Lisp +is compliant, it will still produce a lot of output on the +console, but no "ERROR!!" messages; and it will produce +only empty ".erg" files (that should get deleted away). + diff --git a/src/ansi-tests/alltest.lisp b/src/ansi-tests/alltest.lisp new file mode 100644 index 000000000..7b5684c9b --- /dev/null +++ b/src/ansi-tests/alltest.lisp @@ -0,0 +1,3309 @@ +;;; based on v1.7 -*- mode: lisp -*- +;; **************************************************************************** +;; * kurztest xcl * +;; **************************************************************************** +;; kap. 1 einfuehrung +;; ---------------------------------------------------------------------------- +;; kap. 2 datentypen +;; ---------------------------------------------------------------------------- +;; kap. 3 gueltigkeitsbereiche +;; ---------------------------------------------------------------------------- +;; kap. 4 typspezifier +;; ---------------------------------------------------------------------------- +;; +;; deftype, coerce, type-of +;; +;; kap. 5 programmstrukturen +;; ---------------------------------------------------------------------------- +;; +;; lambda-listen +(in-package :cl-user) + +(my-assert + ((lambda (a b) + (+ a (* b 3))) + 4 5) + 19) + +(my-assert + ((lambda (a &optional (b 2)) + (+ a (* b 3))) + 4 5) + 19) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) + (list a b c d x))) + (2 nil 3 nil nil)) + +(my-assert + ((lambda (a b &key c d) + (list a b c d)) + 1 2) + (1 2 nil nil)) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) + 1) + (1 3 nil 1 nil)) + +(my-assert + ((lambda (x &aux (a 3) (b 4)) + (+ x (* a b))) + 2) + 14) + +(my-assert + ((lambda (x y &optional a b &rest z &key c (d y) &aux (u 3) (v 4)) + (+ x y a (* b (car z)) c (* d u) v)) + 3 4 5 2 7 :c 6 :d 8) + error) + +(my-assert + ((lambda (x y) + ((lambda (a b) + (list a b)) + 'u 'v)) + 5 6) + (u v)) + +(my-assert + ((lambda (x &allow-other-keys) + (list x y)) + 2 :y 3) + error) + +(my-assert + lambda-list-keywords + #+xcl (&optional &rest &key &allow-other-keys &aux &body &whole system::&environment) + #+clisp (&optional &rest &key &allow-other-keys &aux &body &whole &environment) + #+(or akcl ecls) + (&optional &rest &key &allow-other-keys &aux &whole &environment &body) + #+(or allegro cmu sbcl) + (&optional &rest &key &aux &body &whole &allow-other-keys &environment) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (let ((s (prin1-to-string lambda-parameters-limit ))) + (or #+xcl (equal s "128") + #+clisp (equal s "65536") + #+clisp (equal s "4294967296") + #+akcl (equal s "64") + #+allegro (equal s "16384") + #+(or cmu sbcl sbcl) (equal s "536870911") + ) ) + t) + +;; defvar, defconstant, defparameter, eval-when + +;; kap 6 praedikate +;; ---------------------------------------------------------------------------- + +(my-assert + (typep 'nil 'null) + t) + +(my-assert + (typep (list 'a 'b 'c) 'null) + nil) + +(my-assert + (typep 'abc 'symbol) + t) + +(my-assert + (typep 4 'atom) + t) + +(my-assert + (typep 55 'cons) + nil) + +(my-assert + (typep (list 'a (list 'b 'c)) 'list) + t) + +(my-assert + (typep 5/8 'number) + t) + +(my-assert + (typep -800 'integer) + t) + +(my-assert + (typep 5/7 'rational) + t) + +(my-assert + (typep 2.718 'float) + t) + +(my-assert + (typep #c(1.23 3.56) 'float) + nil) + +(my-assert + (typep #\a 'character) + t) + +(my-assert + (typep "abc" 'string) + t) + +(my-assert + (typep '#(1 2 3) 'string) + nil) + +(my-assert + (typep '#(a b c) 'bit-vector) + nil) + +(my-assert + (typep '#(a b c) 'vector) + t) + +(my-assert + (typep "abc" 'vector) + t) + +(my-assert + (typep '#(1 2 3 4) 'simple-vector) + t) + +(my-assert + (typep 3 'simple-vector) + nil) + +(my-assert + (typep "a b cd" 'simple-string) + t) + +(my-assert + (typep 'abc 'simple-string) + nil) + +(my-assert + (typep #*1101 'simple-bit-vector) + t) + +(my-assert + (typep '#(1 0 0 1) 'simple-bit-vector) + nil) + +(my-assert + (typep '#2a((a b)(c d)) 'array) + t) + +(my-assert + (setq x 7) + 7) + +(my-assert + (typep x 'compiled-function) + nil) + +(my-assert + (typep x 'common) + error) + +(unintern 'x) + +(my-assert + (subtypep 'character 'number) + nil) + +(my-assert + (subtypep 'number 'character) + nil) + +(my-assert + (subtypep 'string 'number) + nil) + +(my-assert + (subtypep 'complex 'number) + t) + +(my-assert + (subtypep 'float 'number) + t) + +(my-assert + (subtypep 'fixnum 'number) + t) + +(my-assert + (subtypep 'rational 'number) + t) + +(my-assert + (subtypep 'float 'complex) + nil) + +(my-assert + (subtypep 'integer 'rational) + t) + +(my-assert + (subtypep 'number 'vector) + nil) + +(my-assert + (subtypep 'vector 'array) + t) + +(my-assert + (subtypep 'number 'array) + nil) + +(my-assert + (null 'nil) + t) + +(my-assert + (symbolp *standard-input*) + nil) + +(my-assert + (symbolp 'car) + t) + +(my-assert + (atom 'abc) + t) + +(my-assert + (consp (acons 'x 'y 'a)) + #+xcl error + #+(or clisp akcl allegro cmu sbcl sbcl ecls) t + #-(or xcl clisp akcl allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + (listp (list (append (cons 'a 'b) 'c))) + t) + +(my-assert + (listp 'a) + nil) + +(my-assert + (listp nil) + t) + +(my-assert + (listp '(a b c)) + t) + +(my-assert + (numberp #*101) + nil) + +(my-assert + (numberp -5) + t) + +(my-assert + (integerp 5) + t) + +(my-assert + (integerp #\+) + nil) + +(my-assert + (rationalp 0) + t) + +(my-assert + (floatp -5) + nil) + +(my-assert + (floatp (read-from-string "1.0e30")) + t) + +(my-assert + (floatp 123.4) + t) + +(my-assert + (complexp 1/2) + nil) + +(my-assert + (complexp #c(2 3)) + t) + +(my-assert + (characterp #\1) + t) + +(my-assert + (stringp "abc") + t) + +(my-assert + (stringp :+*/-) + nil) + +(my-assert + (bit-vector-p (read-from-string "#5*01110")) + t) + +(my-assert + (vectorp "abc") + t) + +(my-assert + (simple-vector-p #*101) + nil) + +(my-assert + (simple-string-p "abc") + t) + +(my-assert + (simple-string-p :+*/-) + nil) + +(my-assert + (simple-bit-vector-p #*101) + t) + +(my-assert + (arrayp (read-from-string "#7(2 4 3)")) + t) + +(my-assert + (arrayp '(read-from-string "#1a 5.77")) + nil) + +(my-assert + (packagep (read-from-string "#5*01110")) + nil) + +(my-assert + (packagep *package*) + t) + +(my-assert + (functionp 'atom) + #-(or cltl2 clisp) t + #+(or cltl2 clisp) nil) + +(my-assert + (compiled-function-p 'do) + nil) + +;; commonp + +(my-assert + (eq (list 1 2 3 4 5) + (copy-list (list 1 2 3 4 5))) + nil) + +(my-assert + (setq x (list (cons 1 'a) (cons 2 'b) (cons 3 'c)) ) + ((1 . a) (2 . b) (3 . c))) + +(my-assert + (eq (cadr x) (cadr (copy-alist x))) + nil) + +(unintern 'x) + +(my-assert + (eq #\a #\a) + t) + +(my-assert + (booleanp (eq "Foo" "Foo")) + t) + +(my-assert + (eq "Foo" (copy-seq "Foo")) + nil) + +(my-assert + (eql #c(3.0 -4.0) #c(3 -4)) + nil) + +(my-assert + (eql (cons 'a 'b) (cons 'a 'c)) + nil) + +(my-assert + (equal (list 1 2 3 4 5) (copy-list (list 1 2 3 4 5))) + t) + +(my-assert + (equal x (copy-alist x)) + t) + +(my-assert + (equal 3 3) + t) + +(my-assert + (equal 3 3.0) + nil) + +(my-assert + (equal 3.0 3.0) + t) + +(my-assert + (equal #c(3 -4) #c(3 -4)) + t) + +(my-assert + (equalp (list 1 2 3 4 5) (copy-list (list 1 2 3 4 5))) + t) + +(my-assert + (equalp " foo" " FOO") + t) + +(my-assert + (equalp " fou" " FOO") + nil) + +(my-assert + (not 1) + nil) + +(my-assert + (not nil) + t) + +(my-assert + (and (eq 1 2) (eq 2 3) (eq 3 4) (eq 4 4)) + nil) + +(my-assert + (and (eq 1 2) (eq 3 3) (eq 3 4) (eq 4 4)) + nil) + +(my-assert + (or (eq 2 2) (eq 3 3) (eq 3 4) (eq 4 4)) + t) + +(my-assert + (or (eq 1 2) (eq 2 3) (eq 3 4) (eq 4 5)) + nil) + +;; kap 7 kontrollstructuren +;; ---------------------------------------------------------------------------- + +;; quote, function, symbol-value, symbol-function, boundp, fboundp, +;; special-form-p, setq, psetq, set, makunbound, fmakunbound, + +(my-assert + (setq li1 (list 'a (list 'b) + (list (list 'c) + (list 'd)))) + (a (b) ((c) (d)))) + +(my-assert + (setq vec1 (vector 0 1 2 3)) + #(0 1 2 3)) + +(my-assert + (setf (nth 1 li1) 'uu) + uu) + +(my-assert + (eval 'li1) + (a uu ((c) (d)))) + +(my-assert + (setf (elt li1 1) 'oo) + oo) + +(my-assert + (setf (elt vec1 1) 'oo) + oo) + +(my-assert + (eval 'li1) + (a oo ((c) (d)))) + +(my-assert + (eval 'vec1) + #(0 oo 2 3)) + +(my-assert + (setf (rest li1) '((ww))) + ((ww))) + +(my-assert + (eval 'li1) + (a (ww))) + +(my-assert + (setf (first li1) 'aa) + aa) + +(my-assert + (first li1) + aa) + +(my-assert + (setf (second li1) 'bb) + bb) + +(my-assert + (eval 'li1) + (aa bb)) + +(my-assert + (setf (rest li1) (list 2 3 4 5 6 7 8 9 10)) + (2 3 4 5 6 7 8 9 10)) + +(my-assert + (setf (second li1) 22) + 22) + +(my-assert + (eval 'li1) + (aa 22 3 4 5 6 7 8 9 10)) + +(my-assert + (setf (third li1) '33) + 33) + +(my-assert + (setf (fourth li1) '44) + 44) + +(my-assert + (setf (fifth li1) '55) + 55) + +(my-assert + (setf (sixth li1) '66) + 66) + +(my-assert + (setf (seventh li1) '77) + 77) + +(my-assert + (setf (eighth li1) '88) + 88) + +(my-assert + (setf (ninth li1) '99) + 99) + +(my-assert + (setf (tenth li1) '1010) + 1010) + +(my-assert + (eval 'li1) + (aa 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (first li1) '(((a)))) + (((a)))) + +(my-assert + (setf (caaar li1) 'uu) + uu) + +(my-assert + (caaar li1) + uu) + +(my-assert + (car li1) + ((uu))) + +(my-assert + (setf (caar li1) 'oo) + oo) + +(my-assert + (eval 'li1) + ((oo) 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (car li1) 'ii) + ii) + +(my-assert + (eval 'li1) + (ii 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (cdddr li1) 'pp) + pp) + +(my-assert + (eval 'li1) + (ii 22 33 . pp)) + +(my-assert + (setf (caddr li1) '333) + 333) + +(my-assert + (eval 'li1) + (ii 22 333 . pp)) + +(my-assert + (setf (svref vec1 2) 'kk) + kk) + +(my-assert + (eval 'vec1) + #(0 oo kk 3)) + +(unintern 'vec1) +(unintern 'li1) + +(my-assert + (setf (get 'a 'b) 'uu) + uu) + +(my-assert + (get 'a 'b) + uu) + +(my-assert + (setf (getf + (cadr + (setq xx + (list 'aaa + (list 'i1 'v1 'i2 'v2)))) + 'i2) + 'v222) + v222) + +(my-assert + (eval 'xx) + (aaa (i1 v1 i2 v222))) + +(my-assert + (getf (cadr xx) 'i2) + v222) + +(my-assert + (getf (cadr xx) 'i1) + v1) + +(unintern 'xx) + +(my-assert + (setf (documentation 'beispiel 'typ1) "doc 1") + "doc 1") + +(my-assert + (setf (documentation 'beispiel 'typ2) "doc 2") + "doc 2") + +(my-assert + (documentation 'beispiel 'typ2) + #+xcl (typ2 . "doc 2") + #-xcl "doc 2") + +(my-assert + (setf (documentation 'beispiel 'typ2) "doc 3") + "doc 3") + +(my-assert + (documentation 'beispiel 'typ2) + #+xcl (typ2 . "doc 3") + #-xcl "doc 3") + +(my-assert + (symbol-plist 'beispiel) + #+xcl (documentation ((typ2 . "doc 3") (typ1 . "doc 1"))) + #+clisp (system::documentation-strings (typ2 "doc 3" typ1 "doc 1")) + #+allegro (excl::%documentation ((typ2 . "doc 3") (typ1 . "doc 1"))) + #+(or cmu sbcl ecls) nil + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + (setf (symbol-value 'xx) 'voelligneu) + voelligneu) + +(my-assert + (eval 'xx) + voelligneu) + +(unintern 'xx) + +;; psetf, shiftf, rotatef, define-modify-macro, defsetf, define-setf-method, +;; get-setf-method, get-setf-method-multiple-value, apply, funcall, progn, +;; prog1, prog2, + +(my-assert + (let ((x (list 'a 'b 'c))) + (rplacd (last x) x) + (list-length x)) + nil) + +;; let*, compiler-let, progv, flet, labels, macrolet, if, when, unless, cond, +;; case, typecase, block, loop, do, do*, dolist, dotimes, + +(my-assert + (mapcar (function (lambda (x) (list x))) (list 'a 'b 'c)) + ((a) (b) (c))) + +(my-assert + (mapc (function + (lambda (x y z) + (list x y z))) + (list 'a 'b 'c) + (list 1 2 3) + (list 'u 'i 'v)) + (a b c)) + +(my-assert + (mapl (function (lambda (x y z) (list x y z))) (list 'a 'b 'c) (list 1 2 3) + (list 'u 'i 'v)) + (a b c)) + +(my-assert + (maplist (lambda (x y z) (list x y z)) + (list 'a 'b 'c) + (list 1 2 3) + (list 'u 'i 'v)) + (((a b c) (1 2 3) (u i v)) ((b c) (2 3) (i v)) ((c) (3) (v)))) + +(my-assert + (mapcon (lambda (x y z) (list x y z)) + (list 'a 'b) + (list 1 2 3) + (list 'u 'i 'v)) + ((a b) (1 2 3) (u i v) (b) (2 3) (i v))) + +(my-assert + (mapcan (lambda (x y z) (list x y z)) + (list 'a 'b 'c) + (list 1 2 3) + (list 'u 'i 'v)) + (a 1 u b 2 i c 3 v)) + +;; tagbody, go, multiple-value-list, multiple-value-call, multiple-value-prog1, +;; multiple-value-bind, multiple-value-setq, values, values-list, catch, + +;; unwind-protect, throw, + +;; kap 8 macros +;; ---------------------------------------------------------------------------- + +;; macro-function, defmacro, macroexpand, macroexpand-1, + +;; kap 9 declarationen +;; ---------------------------------------------------------------------------- + +;; declare, locally, proclaim, the, + +;; kap 10 symbole +;; ---------------------------------------------------------------------------- + +;; get, remprop, symbol-plist, getf, remf, get-properties, symbol-name, + +;; make-symbol, copy-symbol, gensym, gentemp, symbol-package, + +(my-assert + (keywordp 36) + nil) + +(my-assert + (keywordp :rename) + t) + +;; kap 11 pakete +;; ---------------------------------------------------------------------------- + +;; find-package, in-package, list-all-packages, make-package, package-name, +;; package-nicknames, package-shadowing-symbols, package-use-list, +;; package-used-by-list, rename-package, unuse-package, use-package, intern, +;; unintern, find-symbol, export, unexport, import, shadowing-import, shadow, +;; find-all-symbols, do-symbols, do-external-symbols, do-all-symbols, +;; provide, require, + +;; kap 12 zahlen +;; ---------------------------------------------------------------------------- + +(my-assert + (zerop -456) + nil) + +(my-assert + (zerop 0) + t) + +(my-assert + (plusp 3) + t) + +(my-assert + (plusp 3453786543987565) + t) + +(my-assert + (minusp -456) + t) + +(my-assert + (oddp -1) + t) + +(my-assert + (oddp 0) + nil) + +(my-assert + (evenp -456) + t) + +(my-assert + (evenp -345) + nil) + +(my-assert + (= 5/2 2.5) + t) + +(my-assert + (/= 3.0 3) + nil) + +(my-assert + (/= 3.0 #c(3.0 1.0)) + t) + +(my-assert + (< 3.0 3) + nil) + +(my-assert + (< 3 3.0 3 #c(3.0 0.0)) + #+(or allegro cmu sbcl sbcl) nil + #-(or allegro cmu sbcl sbcl) error) + +(my-assert + (< -5 -4 -2 0 4 5) + t) + +(my-assert + (> 8 7 6 5 4) + t) + +(my-assert + (> 3 3.0 3 #c(3.0 0.0)) + #+(or allegro cmu sbcl sbcl) nil + #-(or allegro cmu sbcl sbcl) error) + +(my-assert + (<= 3.0 3) + t) + +(my-assert + (<= 3 3) + t) + +(my-assert + (<= 1 3 3 2 5) + nil) + +(my-assert + (<= 5/2 2.5) + t) + +(my-assert + (>= -5 -4 -2 0 4 5) + nil) + +(my-assert + (max 1 3 2 -7) + 3) + +;; min, + +(my-assert + (+ 1 1/2 0.5 #c(3.0 5.5)) + #c(5.0 5.5)) + +(my-assert + (- 3 0 3 5 -6) + 1) + +(my-assert + (- #c(0 6) 1/4 0.5 7) + #c(-7.75 6.0)) + +(my-assert + (* 7 6 5 4 3 2 1) + 5040) + +(my-assert + (* 2 2 2.0 2) + 16.0) + +(my-assert + (/ -8) + -1/8) + +(my-assert + (/ 4 2) + 2) + +(my-assert + (1+ 0) + 1) + +(my-assert + (1+ #c(0 1)) + #c(1 1)) + +(my-assert + (1- 5.0) + 4.0) + +;; incf, decf, + +(my-assert + (conjugate #c(3/5 4/5)) + #c(3/5 -4/5)) + +(my-assert + (gcd 91 -49) + 7) + +(my-assert + (lcm 14 35) + 70) + +(my-assert + (prin1-to-string (exp 1) ) + "2.7182817") ; "2.718282" + +(my-assert + (expt #c(0 1) 2) + -1) + +(my-assert + (prin1-to-string (expt 2 #c(0 1)) ) + "#C(0.7692389 0.63896126)") ; "#C(0.7692389 0.6389612)" + +(my-assert + (prin1-to-string (log -3 10) ) + "#C(0.47712126 1.3643764)") ; "#C(0.4771213 1.364376)" + +(my-assert + (log 3 0) + #+(or xcl cmu sbcl sbcl) 0 + #+allegro 0.0 + #-(or xcl allegro cmu sbcl sbcl) error) + +(my-assert + (sqrt 9) + 3.0) + +(my-assert + (sqrt -9.0) + #c(0.0 3.0)) + +(my-assert + (isqrt 9) + 3) + +(my-assert + (isqrt 26) + 5) + +(my-assert + (abs 6) + 6) + +(my-assert + (abs -6) + 6) + +;; phase, + +(my-assert + (signum 0) + 0) + +(my-assert + (signum -4) + -1) + +(my-assert + (signum 4) + 1) + +(my-assert + (prin1-to-string (sin (* 8 (/ pi 2))) ) + #+xcl "-4.576950980887866D-17" + #+clisp "2.0066230454737344098L-19" + #+akcl "-4.898425415289509E-16" + #+(or allegro cmu sbcl sbcl ecls) "-4.898425415289509d-16" + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string (sin (expt 10 3)) ) + "0.82687956") ; "0.8268796" + +(my-assert + (cos 0) + 1.0) + +(my-assert + (prin1-to-string (cos (/ pi 2)) ) + #+xcl "5.721188726109832D-18" + #+clisp "-2.5082788076048218878L-20" + #+akcl "6.1230317691118863E-17" + #+(or allegro cmu sbcl sbcl ecls) "6.123031769111886d-17" + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string (tan 1) ) + "1.5574077") ; "1.557408" + +(my-assert + (prin1-to-string (tan (/ pi 2)) ) + #+xcl "1.747888503373944D17" + #+clisp "-3.986797629004264116L19" + #+akcl "1.6331778728383844E16" + #+ecls "1.6331778728383844d16" + #+(or allegro cmu sbcl sbcl) "1.6331778728383844d+16" + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string (cis -1) ) + "#C(0.5403023 -0.84147096)") ; "#C(0.5403023 -0.8414709)" + +(my-assert + (cis 2.5) + #c(-0.8011436 0.5984721)) + +(my-assert + (prin1-to-string (asin -1) ) + "-1.5707964") ; "-1.570796" + +(my-assert + (asin 0) + 0.0) + +(my-assert + (asin 2) + #+(or cmu sbcl sbcll) + #c(1.5707964 -1.3169578) + #-(or cmu sbcl sbcll) + #c(1.5707964 -1.316958)) + +(my-assert + (prin1-to-string (acos 0) ) + "1.5707964") ; "1.570796" + +(my-assert + (prin1-to-string (acos -1) ) + "3.1415927") ; "3.141593" + +(my-assert + (prin1-to-string (acos 2) ) + #+xcl + "#C(0.0 1.316958)" + #+clisp + "#C(0 1.316958)" + #+allegro + "#c(0.0 1.316958)" + #+(or cmu sbcl sbcl ecls) + "#C(0.0 1.3169578)" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (acos 1.00001) + #+ganz-korrekt + #c(0.0 0.0044721322) + #+xcl + #c(0.0 0.004475157) + #+clisp-korrekt + #c(0.0 0.0044751678) ; da schon 1.00001 gerundet wurde + #+clisp + #c(0.0 0.0044751023) ; i * ln(x+sqrt(x^2-1)) + #+clisp-anders + #c(0.0 0.0044752206) ; i * ln(x+sqrt((x-1)*(x+1))) + #+allegro + #c(0.0 0.004475168) + #+(or cmu sbcl sbcll) + #c(0.0 0.0044751678) + #-(or xcl clisp allegro cmu sbcl sbcl) + #c(0.0 0.0044721322)) + +(my-assert + (atan 1) + #+(or xcl allegro cmu sbcl sbcl ecls) 0.7853982 + #+clisp 0.7853981 + #-(or xcl allegro clisp cmu sbcl sbcl ecls) unknown) + +(my-assert + (prin1-to-string pi ) + #+xcl "3.141592653589793D0" + #+clisp "3.1415926535897932385L0" + #+(or allegro cmu sbcl sbcl ecls) "3.141592653589793d0" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (sinh 0) + 0.0) + +(my-assert + (prin1-to-string (sinh #c(5.0 -9.6)) ) + #+(or cmu sbcl sbcll) + "#C(-73.06699 12.936809)" + #-(or cmu sbcl sbcll) + "#C(-73.06699 12.93681)") + +(my-assert + (cosh 0) + 1.0) + +(my-assert + (prin1-to-string (cosh 1) ) + #+(or cmu sbcl sbcll) "1.5430807" ; round-off error + #-(or cmu sbcl sbcll) "1.5430806") ; "1.543081" + +(my-assert + (tanh 50) + 1.0) + +(my-assert + (prin1-to-string (tanh 0.00753) ) + #-allegro "0.0075298576" + #+allegro "0.0075298795") ; "0.007529857" + +(my-assert + (prin1-to-string (asinh 0.5) ) + #-(or allegro cmu sbcl sbcl) "0.48121184" + #+(or allegro cmu sbcl sbcl) "0.4812118") ; "0.4812118" + +(my-assert + (prin1-to-string (asinh 3/7) ) + #-(or clisp allegro cmu sbcl sbcl) "0.4164308" + #+clisp "0.4164307" ; rundungsfehler + #+(or allegro cmu sbcl sbcl) "0.41643077") + +(my-assert + (acosh 0) + #c(0 1.5707964)) + +(my-assert + (acosh 1) + 0) + +(my-assert + (acosh -1) + #c(0 3.1415927)) + +(my-assert + (prin1-to-string (atanh 0.5) ) + "0.54930615") ; "0.5493061" + +(my-assert + (prin1-to-string (atanh 3/7) ) + #-(or clisp allegro cmu sbcl sbcl) "0.4581454" + #+clisp "0.4581453" ; rundungsfehler + #+(or allegro cmu sbcl sbcl) "0.45814538") + +(my-assert + (= (sin (* #c(0 1) 5)) (* #c(0 1) (sinh 5))) + t) + +(my-assert + (= (cos (* #c(0 1) 5)) (cosh 5)) + t) + +(my-assert + (= (tan (* #c(0 1) 5)) (* #c(0 1) (tanh 5))) + t) + +(my-assert + (= (sinh (* #c(0 1) 5)) (* #c(0 1) (sin 5))) + t) + +(my-assert + (= (cosh (* #c(0 1) 5)) (cos 5)) + t) + +(my-assert + (float 1) + 1.0) + +(my-assert + (float 0.5) + 0.5) + +(my-assert + (rational 2) + 2) + +(my-assert + (rational 2.0) + 2) + +(my-assert + (rational 2.5) + 5/2) + +(my-assert + (rationalize 2.5) + 5/2) + +(my-assert + (rationalize 7/3) + 7/3) + +(my-assert + (rationalize pi) + #+xcl 28296953155597409/9007199254740992 + #+clisp 8717442233/2774848045 + #+ecls 884279719003555/281474976710656 + #+(or allegro cmu sbcl sbcl) 245850922/78256779 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + (numerator 5/2) + 5) + +(my-assert + (numerator (/ 8 -6)) + -4) + +(my-assert + (denominator 5/2) + 2) + +(my-assert + (denominator (/ 8 -6)) + 3) + +(my-assert + (gcd (numerator 7/9) (denominator 7/9)) + 1) + +(my-assert + (floor 2.6) + 2) + +(my-assert + (floor 2.5) + 2) + +(my-assert + (ceiling 2.6) + 3) + +(my-assert + (ceiling 2.5) + 3) + +(my-assert + (ceiling 2.4) + 3) + +(my-assert + (truncate 2.6) + 2) + +(my-assert + (truncate 2.5) + 2) + +(my-assert + (truncate 2.4) + 2) + +(my-assert + (round 2.6) + 3) + +(my-assert + (round 2.5) + 2) + +(my-assert + (round 2.4) + 2) + +(my-assert + (mod 13 4) + 1) + +(my-assert + (mod -13 4) + 3) + +(my-assert + (prin1-to-string (rem 13.4 1) ) + #-(or clisp allegro cmu sbcl sbcl) "0.4" ; + #+xcl "0.3999996" + #+(or clisp allegro cmu sbcl sbcl) "0.39999962") ; rundungsfehler + +(my-assert + (ffloor 2.6) + 2) + +(my-assert + (ffloor 2.5) + 2) + +(my-assert + (ffloor 2.4) + 2) + +(my-assert + (fceiling -0.3) + 0) + +(my-assert + (fceiling -0.7) + 0) + +(my-assert + (fceiling -2.4) + -2) + +(my-assert + (ftruncate 2.5) + 2.0) + +(my-assert + (ftruncate 2.4) + 2.0) + +(my-assert + (fround -0.7) + -1.0) + +(my-assert + (fround -2.4) + -2.0) + +(my-assert + (decode-float 35.0) + 0.546875) + +(my-assert + (decode-float 3.5s0) + 0.875s0) + +(my-assert + (scale-float 2.5 5) + 80.0) + +(my-assert + (scale-float 0.7541 2) + 3.0164) + +(my-assert + (float-radix 2.5) + 2) + +(my-assert + (float-radix 3.5d0) + 2) + +;; float-digits, float-precision, float-sign, integer-decode-float, + +(my-assert + (complex 1/4 7.3) + #c(0.25 7.3)) + +(my-assert + (complex 1 0) + 1) + +(my-assert + (realpart 5) + 5) + +(my-assert + (realpart #c(1.4 0.0)) + 1.4) + +(my-assert + (imagpart 5) + 0) + +(my-assert + (imagpart #c(1.4 0.0)) + 0.0) + +;; logand, logandc1, logandc2, logeqv, logior, lognand, lognor, lognot, +;; logorc1, logorc2, logtest, logxor, logbitp, ash, + +(my-assert + (logcount 13) + 3) + +(my-assert + (logcount -13) + 2) + +(my-assert + (integer-length 0) + 0) + +(my-assert + (integer-length 1) + 1) + +;; byte, byte-position, byte-size, ldb, ldb-test, mask-field, dpb, deposit-field, + +;; random, + +#+xcl +(my-assert + (random-state-p + (eval (read-from-string "(sys::%set-type-pointer sys::%type-random-state 1)"))) + t) + +;; make-random-state, + +(my-assert + boole-clr + 0) + +(my-assert + boole-set + #+(or xcl allegro cmu sbcl sbcl) 1 + #+(or clisp ecls) 15 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-1 + #+(or xcl allegro cmu sbcl sbcl) 2 + #+clisp 10 + #+ecls 3 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-2 + #+(or xcl allegro cmu sbcl sbcl) 3 + #+clisp 12 + #+ecls 5 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-c1 + #+(or xcl allegro cmu sbcl sbcl) 4 + #+clisp 5 + #+ecls 12 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-c2 + #+(or xcl allegro cmu sbcl sbcl) 5 + #+clisp 3 + #+ecls 10 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-and + #+(or xcl allegro cmu sbcl sbcl) 6 + #+clisp 8 + #+ecls 1 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-ior + #+(or xcl allegro cmu sbcl sbcl) 7 + #+clisp 14 + #+ecls 7 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-xor + #+(or xcl allegro cmu sbcl sbcl) 8 + #+(or clisp ecls) 6 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-eqv + #+(or xcl allegro cmu sbcl sbcl) 9 + #+(or clisp ecls) 9 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-nand + #+(or xcl allegro cmu sbcl sbcl) 10 + #+clisp 7 + #+ecls 14 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-nor + #+(or xcl allegro cmu sbcl sbcl) 11 + #+clisp 1 + #+ecls 8 + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + boole-andc1 + #+(or xcl allegro cmu sbcl sbcl) 12 + #+(or clisp ecls) 4 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-andc2 + #+(or xcl allegro cmu sbcl sbcl) 13 + #+(or clisp ecls) 2 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-orc1 + #+(or xcl allegro cmu sbcl sbcl) 14 + #+(or clisp ecls) 13 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + boole-orc2 + #+(or xcl allegro cmu sbcl sbcl) 15 + #+(or clisp ecls) 11 + #-(or xcl clisp allegro cmu sbcl sbcl ecls) unknown) + +(my-assert + (let ((s (prin1-to-string most-positive-fixnum ))) + (or #+(or xcl clisp) (equal s "16777215") + #+clisp (equal s "33554431") + #+clisp (equal s "67108863") + #+clisp (equal s "4294967295") + #+(or allegro cmu sbcl sbcl) (equal s "536870911") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string most-negative-fixnum ))) + (or #+(or xcl clisp) (equal s "-16777216") + #+clisp (equal s "-33554432") + #+clisp (equal s "-67108864") + #+clisp (equal s "-4294967296") + #+(or allegro cmu sbcl) (equal s "-536870912") + ) ) + t) + +(my-assert + (prin1-to-string most-positive-short-float ) + #+xcl "1.701S38" + #+clisp "1.7014s38" + #+allegro "3.4028232e+38" + #+(or cmu sbcl sbcll) "3.4028235e+38" + #+ecls "3.4028235e38" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string least-positive-short-float ) + #+xcl "2.939S-39" + #+clisp "2.93874s-39" + #+(or allegro cmu sbcl sbcl) "1.4012985e-45" + #+ecls "1.401298E-45" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string least-negative-short-float ) + #+xcl "-2.939S-39" + #+clisp "-2.93874s-39" + #+(or allegro cmu sbcl sbcl) "-1.4012985e-45" + #+ecls "-1.401298E-45" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string most-negative-short-float ) + #+xcl "-1.701S38" + #+clisp "-1.7014s38" + #+allegro "-3.4028232e+38" + #+(or cmu sbcl sbcll) "-3.4028235e+38" + #+ecls "-3.402823E38" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (let ((s (prin1-to-string most-positive-single-float ))) + (or #+xcl (equal s "1.701411E38") + #+clisp (equal s "1.7014117E38") + #+clisp (equal s "3.4028235E38") + #+allegro (equal s "3.4028232e+38") + #+(or cmu sbcl sbcll) (equal s "3.4028235e+38") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string least-positive-single-float ))) + (or #+(or xcl clisp) (equal s "2.938736E-39") + #+clisp (equal s "1.1754944E-38") + #+(or allegro cmu sbcl sbcl) (equal s "1.4012985e-45") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string least-negative-single-float ))) + (or #+(or xcl clisp) (equal s "-2.938736E-39") + #+clisp (equal s "-1.1754944E-38") + #+(or allegro cmu sbcl sbcl) (equal s "-1.4012985e-45") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string most-negative-single-float ))) + (or #+xcl (equal s "-1.701411E38") + #+clisp (equal s "-1.7014117E38") + #+clisp (equal s "-3.4028235E38") + #+allegro (equal s "-3.4028232e+38") + #+(or cmu sbcl sbcll) (equal s "-3.4028235e+38") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string most-positive-double-float ))) + (or #+xcl (equal s "1.701411834604692D38") + #+clisp (equal s "8.988465674311579d307") + #+clisp (equal s "1.7976931348623157d308") + #+allegro (equal s "4.494232837155787d+307") + #+(or cmu sbcl sbcll) (equal s "1.7976931348623157d+308") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string least-positive-double-float ))) + (or #+xcl (equal s "2.938735877055719D-39") + #+clisp (equal s "5.562684646268004d-309") + #+clisp (equal s "2.2250738585072014d-308") + #+allegro (equal s "4.9406564584124657d-324") + #+(or cmu sbcl sbcll) (equal s "4.940656458412465d-324") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string least-negative-double-float ))) + (or #+xcl (equal s "-2.938735877055719D-39") + #+clisp (equal s "-5.562684646268004d-309") + #+clisp (equal s "-2.2250738585072014d-308") + #+allegro (equal s "-4.9406564584124657d-324") + #+(or cmu sbcl sbcll) (equal s "-4.940656458412465d-324") + ) ) + t) + +(my-assert + (let ((s (prin1-to-string most-negative-double-float ))) + (or #+xcl (equal s "-1.701411834604692D38") + #+clisp (equal s "-8.988465674311579d307") + #+clisp (equal s "-1.7976931348623157d308") + #+allegro (equal s "-4.494232837155787d+307") + #+(or cmu sbcl sbcll) (equal s "-1.7976931348623157d+308") + ) ) + t) + +(my-assert + (prin1-to-string most-positive-long-float ) + #+xcl "1.701411834604692D38" + #+clisp "8.8080652584198167656L646456992" + #+allegro "4.494232837155787d+307" + #+(or cmu sbcl sbcll) "1.7976931348623157d+308" + #+ecls "1.797693134862316d308" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string least-positive-long-float ) + #+xcl "2.938735877055719D-39" + #+clisp "5.676615526003731344L-646456994" + #+allegro "4.9406564584124657d-324" + #+(or cmu sbcl ecls) "4.940656458412465d-324" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string least-negative-long-float ) + #+xcl "-2.938735877055719D-39" + #+clisp "-5.676615526003731344L-646456994" + #+allegro "-4.9406564584124657d-324" + #+(or cmu sbcl ecls) "-4.940656458412465d-324" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string most-negative-long-float ) + #+xcl "-1.701411834604692D38" + #+clisp "-8.8080652584198167656L646456992" + #+allegro "-4.494232837155787d+307" + #+(or cmu sbcl sbcll) "-1.7976931348623157d+308" + #+ecls "-1.797693134862316d308" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string short-float-epsilon ) + #+xcl "1.526S-5" + #+clisp "7.6295s-6" + #+allegro "1.1920929e-7" + #+(or cmu sbcl sbcll) "5.960465e-8" + #+ecls "6.258487E-8" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string single-float-epsilon ) + #+xcl "5.960464E-8" + #+clisp "5.960465E-8" + #+allegro "1.1920929e-7" + #+(or cmu sbcl sbcll) "5.960465e-8" + #+ecls "6.258487E-8" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string double-float-epsilon ) + #+xcl "1.387778780781446D-17" + #+(or clisp cmu sbcl sbcl) "1.1102230246251568d-16" + #+allegro "2.220446049250313d-16" + #+ecls "1.165734175856414d-16" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string long-float-epsilon ) + #+xcl "1.387778780781446D-17" + #+clisp "5.4210108624275221706L-20" + #+allegro "2.220446049250313d-16" + #+(or cmu sbcl sbcll) "1.1102230246251568d-16" + #+ecls "1.165734175856414d-16" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string short-float-negative-epsilon ) + #+xcl "1.526S-5" + #+clisp "3.81476s-6" + #+allegro "1.1920929e-7" + #+(or cmu sbcl sbcll) "2.9802325e-8" + #+ecls "3.129244E-8" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string single-float-negative-epsilon ) + #+xcl "5.960464E-8" + #+clisp "2.9802326E-8" + #+allegro "1.1920929e-7" + #+(or cmu sbcl sbcll) "2.9802325e-8" + #+ecls "3.129244E-8" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string double-float-negative-epsilon ) + #+xcl "1.387778780781446D-17" + #+(or clisp cmu sbcl sbcl) "5.551115123125784d-17" + #+allegro "2.220446049250313d-16" + #+ecls "5.828670879282072d-17" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (prin1-to-string long-float-negative-epsilon ) + #+xcl "1.387778780781446D-17" + #+clisp "2.7105054312137610853L-20" + #+allegro "2.220446049250313d-16" + #+(or cmu sbcl sbcll) "5.551115123125784d-17" + #+ecls "5.828670879282072d-17" + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (/ 1 0) + error) + +(my-assert + (/ 1 0.0s0) + error) + +(my-assert + (/ 1 0.0f0) + error) + +(my-assert + (/ 1 0.0d0) + error) + +(my-assert + (/ 1 0.0l0) + error) + +(my-assert + (expt 10.0s0 1000) + error) + +(my-assert + (expt 10.0f0 1000) + error) + +(my-assert + (expt 10.0d0 1000) + error) + +(my-assert + (expt 10.0l0 1000000000) + error) + +;; kap 13 zeichen +;; ---------------------------------------------------------------------------- + +(my-assert + (standard-char-p #\a) + t) + +(my-assert + (standard-char-p 1) + error) + +(my-assert + (graphic-char-p #\a) + t) + +(my-assert + (graphic-char-p 1) + error) + +(my-assert + (characterp + #\a) + t) + +(my-assert + (characterp + #\1) + t) + +(my-assert + (alpha-char-p #\a) + t) + +(my-assert + (alpha-char-p #\$) + nil) + +(my-assert + (upper-case-p #\a) + nil) + +(my-assert + (lower-case-p #\A) + nil) + +(my-assert + (both-case-p #\a) + t) + +(my-assert + (both-case-p #\$) + nil) + +(my-assert + (digit-char-p #\a) + nil) + +(my-assert + (digit-char-p #\5) + 5) + +(my-assert + (alphanumericp #\a) + t) + +(my-assert + (alphanumericp #\$) + nil) + +(my-assert + (char= #\d #\d) + t) + +(my-assert + (char/= #\d #\d) + nil) + +(my-assert + (char< #\z #\0) + nil) + +;; char>, char>=, char<=, + +(my-assert + (char-equal #\d #\d) + t) + +(my-assert + (char-not-equal #\d #\d) + nil) + +(my-assert + (char-lessp #\d #\x) + t) + +(my-assert + (char-lessp #\d #\d) + nil) + +(my-assert + (char-not-greaterp #\d #\d) + t) + +(my-assert + (char-greaterp #\e #\d) + t) + +(my-assert + (char-not-lessp #\e #\d) + t) + +;; char-code, code-char, character, + +(my-assert + (char-upcase #\a) + #\a) + +(my-assert + (char-upcase #\=) + #\=) + +(my-assert + (char= (char-downcase (char-upcase #\x)) #\x) + t) + +(my-assert + (char-downcase #\a) + #\a) + +(my-assert + (char= (char-upcase (char-downcase #\X)) #\X) + t) + +(my-assert + (digit-char 7) + #\7) + +(my-assert + (digit-char 12) + nil) + +;; char-int, int-char, char-name, name-char, + +(my-assert + char-code-limit + #+xcl 128 + #+(or (and clisp (not unicode)) akcl sbcl cmu ecls) 256 + #+(or (and clisp unicode) allegro) 655366 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +;; kap 14 sequenzen +;; ---------------------------------------------------------------------------- + +(my-assert + (elt (symbol-name 'abc) 0) + #\a) + +(my-assert + (subseq (list 'a 'b 'c 'd 'e) 2) + (c d e)) + +(my-assert + (copy-seq '#(a b c)) + #(a b c)) + +(my-assert + (copy-seq (list (list 'a 'b) 'c (list 'd 'e))) + ((a b) c (d e))) + +(my-assert + (length #(a b c d e f)) + 6) + +(my-assert + (length (list 'a 'b 'c 'd 'e 'f)) + 6) + +(my-assert + (nreverse (list 'a + (list 'b + (list 'c) + 'd))) + ((b (c) d) a)) + +(my-assert + (reverse (list 1 2 3 4)) + (4 3 2 1)) + +(my-assert + (make-sequence 'vector 4 :initial-element 'o) + #(o o o o)) + +(my-assert + (make-sequence 'list 4 :initial-element 'o) + (o o o o)) + +(my-assert + (concatenate 'list (list 'a 'b 'c) (list 1 2)) + (a b c 1 2)) + +(my-assert + (map 'list 'list + (list #\a #\b #\c) + (list #\1 #\2 #\3)) + ((#\a #\1) (#\b #\2) (#\c #\3))) + +(my-assert + (map 'list 'list (list 'a 'b 'c) (list 1 2 3)) + ((a 1) (b 2) (c 3))) + +(my-assert + (some 'null (list 'a 'b nil 't 'e)) + t) + +(my-assert + (every 'atom (list 'a 8 #(a b))) + t) + +(my-assert + (notany 'eq + (list 'a 'b 'c 'd 'e 4) + (list 'i 'j 'k 'l 'm 4)) + nil) ;? t + +(my-assert + (notevery 'eq '#(u) + (list 'a 'x 'u)) + t) + +(my-assert + (reduce 'list '(a) :from-end nil :initial-value nil) + + (nil a)) + +(my-assert + (reduce 'list + (list 'a 'b 'c 'd) + :from-end nil + :initial-value 'iii) + ((((iii a) b) c) d)) + +(my-assert + (reduce 'list (list 'a 'b 'c 'd) :from-end t) + (a (b (c d)))) + +(my-assert + (fill '#(a b c d) 'i :start 1 :end 3) + #(a i i d)) + +(my-assert + (replace '#(a b c d) '#(i j) :start1 1) + #(a i j d)) + +(my-assert + (remove 'numberp '#(y a 4 a c 9 a d 2 3) + :count 1 :from-end t) + #(y a 4 a c 9 a d 2 3)) + +(my-assert + (remove 'a + (list 'a 1 'b 'a '2 'a) + :start 1) + (a 1 b 2)) + +(my-assert + (remove-duplicates (list 'a 'b 'c 'a 'd 'a) + :start 1) + (a b c d a)) + +(my-assert + (remove-if 'numberp '#(y a 4 a c 9 a d 2 3)) + #(y a a c a d)) + +(my-assert + (remove-if-not 'numberp #(y a 4 a c 9 a d 2 3)) + #(4 9 2 3)) + +(my-assert + (remove-if-not 'numberp #(y a 4 a c 9 a d 2 3) + :count 2 :from-end nil) + #(4 a c 9 a d 2 3)) + +(my-assert + (delete '(a) (list (list 'a 'b) (list 'c 'd) (list 'a)) + :test 'equal) + ((a b) (c d))) + +(my-assert + (delete-if (lambda (x) (eq (car x) 'a)) + (list (list 'a 'b) + (list 'c 'd) + (list 'a))) + ((c d))) + +(my-assert + (delete-if-not 'numberp (list 'a 3 'b 4)) + (3 4)) + +;; delete-duplicates, + +(my-assert + (nsubstitute 'new (list 1 'old) + (list (list 0 'old) (list 1 'old) (list 2 'old)) + :test-not 'equal + :from-end t) + (new (1 old) new)) + +(my-assert + (nsubstitute 'new 'old (list 0 'old 1 'old 2 'old) :end 2) + (0 new 1 old 2 old)) + +(my-assert + (nsubstitute-if 'new 'numberp (list 0 'a 1 'b 2 'c 3 'd) + :count 2 + :end 5) + (new a new b 2 c 3 d)) + +(my-assert + (nsubstitute-if-not 'new 'numberp + (list 0 'a 1 'b 2 'c 3 'd) + :count 2 + :from-end t) + (0 a 1 b 2 new 3 new)) + +(my-assert + (substitute 'new (list 2 'old) + (list (list 1 'old) (list 2 'old) (list 3 'old) (list 4 'old)) + :test 'equal + :start 3) + ((1 old) (2 old) (3 old) (4 old))) + +(my-assert + (substitute-if 'new 'numberp + (list 'a 1 'b 2 'd 3)) + (a new b new d new)) + +(my-assert + (substitute-if-not 'new 'numberp (list 'a 1 'b 2 'd 3) + :count 2 + :from-end t) + (a 1 new 2 new 3)) + +(my-assert + (find '0 (list (list 0 'a) (list 1 'a) (list 2 'a) (list 0 'b)) + :test '= + :from-end t + :key 'car + :start 1) + (0 b)) + +(my-assert + (find-if 'numberp (list (list 'a 0) (list 'b 1) (list 'c 2)) + :key 'cadr + :start 3) + nil) + +;; find-if-not, + +(my-assert + (position 'a (list (list 0 'a) (list 1 'b) (list 2 'a) (list 3 'b)) + :test #'(lambda (x y) (eq x (cadr y))) + :start 1) + 2) + +(my-assert + (position 'a + (list (list 0 'a) (list 1 'b) (list 2 'a) (list 3 'b)) + :key 'cadr) + + 0) + +(my-assert + (position-if 'numberp + (list (list 0 'x) (list 1 7.0) (list 2 8)) + :from-end t + :start 1 + :key 'cadr) + 2) + +;; position-if-not, + +(my-assert + (count '(a) + (list 'a (list 'a) 'a (list 'a) 'a 'b) + :test-not 'equal + :key (lambda (x) + (when (atom x) + (list x)))) + 3) + +(my-assert + (count-if-not 'numberp '#(a 3 b 5 7 c d) :start 2 :end 5) + 1) + +;; count-if-not, + +(my-assert + (mismatch (list 'a 'b 'c 3 4 5) + (list 'a 'b 'x 3 4 'b) + :start1 1 + :start2 5 + :end1 2 + :test-not 'eq) + 1) + +(my-assert + (mismatch (list 'a 'b 'c 3 4 5) + (list 'u 'b 'x 3 4 5) + :from-end t) + #+xcl 2 + #-xcl 3) + +(my-assert + (search "ABCD" "0ABIABJBCBC" + :end1 3 + :start1 1 + :start2 0 + :from-end t) + 9) + +(my-assert + (search (list #\A #\B #\C #\D) + "0ABIABJBCBC" + :end1 2 + :start2 0 + :from-end t) + 4) + +(my-assert + (search (list 'a 'b 'c 'd) + (list 0 'a 'b 'i 'a 'b 'j 'b 'c 'b 'c) + :end1 2 + :start2 2) + 4) + +(my-assert + (sort (list (list 'u 3) (list 'i 1) + (list 'a 7) (list 'k 3) + (list 'c 4) (list 'b 6)) + '< + :key 'cadr) + ((i 1) (u 3) (k 3) (c 4) (b 6) (a 7))) + +(my-assert + (stable-sort (list (list 'b 4) (list 'a 3) + (list 'a 2) (list 'b 1) + (list 'c 9) (list 'b 2)) + 'string< + :key 'car) + ((a 3) (a 2) (b 4) (b 1) (b 2) (c 9))) + +(my-assert + (merge 'list + (list 5 1 4 4 7) + (list 2 3 5 6 8 9) + '<) + (2 3 5 1 4 4 5 6 7 8 9)) ;? error + +(my-assert + (merge 'list + (list 1 4 4 7) + (list 2 3 5 6 8 9) + '<) + (1 2 3 4 4 5 6 7 8 9)) ;? error + +;; kap 15 listen +;; ---------------------------------------------------------------------------- + +(my-assert + (car (list 'a 'b 'c 'd 'e 'f 'g)) + a) + +(my-assert + (cdr (list 'a 'b 'c 'd 'e 'f 'g)) + (b c d e f g)) + +(my-assert + (cadr (list 'a 'b 'c 'd 'e 'f 'g)) + b) + +(my-assert + (cddr (list 'a 'b 'c 'd 'e 'f 'g)) + (c d e f g)) + +(my-assert + (caddr (list 'a 'b 'c 'd 'e 'f 'g)) + c) + +(my-assert + (cdddr (list 'a 'b 'c 'd 'e 'f 'g)) + (d e f g)) + +(my-assert + (cadddr (list 'a 'b 'c 'd 'e 'f 'g)) + d) + +(my-assert + (cddddr (list 'a 'b 'c 'd 'e 'f 'g)) + (e f g)) + +(my-assert + (caadr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + ((u v w) x)) + +(my-assert + (cadar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (6 7)) + +(my-assert + (cdaar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (5)) + +(my-assert + (cdadr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (y)) + +(my-assert + (cddar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + nil) + +(my-assert + (caaaar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (1 2 3)) + +(my-assert + (caadar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + 6) + +(my-assert + (caaddr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (q w e)) + +(my-assert + (cadaar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + 5) + +(my-assert + (cadadr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + y) + +(my-assert + (caddar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + nil) + +(my-assert + (cadddr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (a b c)) + +(my-assert + (cdaaar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (4)) + +(my-assert + (cdaadr + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (x)) + +(my-assert + (cdadar + (list (list (list (list (list 1 2 3) + 4) + 5) + (list 6 7)) + (list (list (list 'u 'v 'w) + 'x) + 'y) + (list (list 'q 'w 'e) + 'r) + (list 'a 'b 'c) + 'e 'f 'g)) + (7)) + +(my-assert + (cons 1 2) + (1 . 2)) + +(my-assert + (cons 'a (cons 'b (cons 'c 'nil))) + (a b c)) + +(my-assert + (cons 'a (list 'b 'c 'd)) + (a b c d)) + +(my-assert + (tree-equal 5 (+ 2 3) :test (function eql)) + t) + +(my-assert + (endp 'nil) + t) + +(my-assert + (endp (cons 'a 'b)) + nil) + +(my-assert + (list-length (list 'a 'b 'c 'd)) + 4) + +(my-assert + (let ((x (list 'a 'b 'c))) (rplacd (last x) x) + + (list-length x)) + nil) + +(my-assert + (nth 0 (list 'a 'b 'c 'd)) + a) + +(my-assert + (first (list 1 2 3 4 5 6 7 8 9 10 11)) + 1) + +(my-assert + (second (list 1 2 3 4 5 6 7 8 9 10 11)) + 2) + +(my-assert + (third (list 1 2 3 4 5 6 7 8 9 10 11)) + 3) + +(my-assert + (fourth (list 1 2 3 4 5 6 7 8 9 10 11)) + 4) + +(my-assert + (fifth (list 1 2 3 4 5 6 7 8 9 10 11)) + 5) + +(my-assert + (sixth (list 1 2 3 4 5 6 7 8 9 10 11)) + 6) + +(my-assert + (seventh (list 1 2 3 4 5 6 7 8 9 10 11)) + 7) + +(my-assert + (eighth (list 1 2 3 4 5 6 7 8 9 10 11)) + 8) + +(my-assert + (ninth (list 1 2 3 4 5 6 7 8 9 10 11)) + 9) + +(my-assert + (tenth (list 1 2 3 4 5 6 7 8 9 10 11)) + 10) + +(my-assert + (rest (cons 'a 'b)) + b) + +(my-assert + (nthcdr 1 (list 'a 'b 'c 'd)) + (b c d)) + +(my-assert + (last (list 1 2 3 4 5)) + (5)) + +(my-assert + (last (append (list 1 2 3) 4)) + (3 . 4)) + +(my-assert + (list 'a 'b 'c 'd) + (a b c d)) + +(my-assert + (list* 'a 'b 'c 'd) + (a b c . d)) + +(my-assert + (make-list 4 :initial-element 'o) + (o o o o)) + +(my-assert + (make-list 3 :initial-element 'rah) + (rah rah rah)) + +(my-assert + (append (list 'a 'b 'c) + (list 'd 'e 'f) 'nil '(g)) + (a b c d e f g)) + +(my-assert + (copy-list (list 1 2 3 4 5)) + (1 2 3 4 5)) + +(my-assert + (copy-list (append (list 1 2 3) 4)) + (1 2 3 . 4)) + +(my-assert + (copy-alist (list 'a 'b)) + (a b)) + +(my-assert + (copy-alist (list (cons 1 'a) (cons 2 'b) (cons 3 'c))) + ((1 . a) (2 . b) (3 . c))) + +(my-assert + (copy-alist (list (list 'a 'b) 'c (list 'd 'e))) + ((a b) c (d e))) + +(my-assert + (copy-tree (list 'a 'b + (list 'c + (list 'd) + (list 'e 'f)) + 'g)) + (a b (c (d) (e f)) g)) + +(my-assert + (revappend (list 'a 'b 'c) (list 'd 'e 'f)) + (c b a d e f)) + +(my-assert + (revappend (list 'a 'b 'c) 'i) + (c b a . i)) ;? error + +(my-assert + (nreconc (list 'a 'b 'c) (list 'i 'j)) + (c b a i j)) + +;; nreconc + +(my-assert + (setq aa nil) + nil) + +(my-assert + (push '1 aa) + (1)) + +(my-assert + (push '2 aa) + (2 1)) + +(my-assert + (pop aa) + 2) + +(my-assert + (pop aa) + 1) + +(my-assert + (pop aa) + nil) + +(my-assert + (setq aa (list 'b 'a)) + (b a)) + +(my-assert + (pushnew 'a aa) + (b a)) + +(my-assert + (pushnew 'c aa) + (c b a)) + +(my-assert + (pushnew 'u (car (setq xx (list nil 'kkk)))) + (u)) + +(my-assert + (pushnew 'u (car xx)) + (u)) + +(my-assert + (pushnew 'v (car xx)) + (v u)) + +(my-assert + (eval 'xx) + ((v u) kkk)) + +(my-assert + (butlast (list 'a 'b 'c) 2) + (a)) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) 6) + nil) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) 1) + (a b c)) + +(my-assert + (ldiff (setq xx (list 'a 'b 'c 'd 'e)) + (cddr xx)) + (a b)) + +(my-assert + (ldiff (setq xx (append (list 'a 'b 'c 'd) + 'e)) + (cddr xx)) + (a b)) + +(unintern 'xx) + +(my-assert + (ldiff (append (list 'a 'b 'c 'd) + 'e) + 'e) + (a b c d)) + +;; rplaca, rplacd + +(my-assert + (nsubst 'a 'b + (list 'u 'b (list 'b) 'c) + :test-not (lambda (x y) + (not (eql x y)))) + (u a (a) c)) + +(my-assert + (nsubst-if 'oo + 'numberp + (list 'a 'b 'c (list 3 (list 4) 0))) + (a b c (oo (oo) oo))) + +(my-assert + (nsubst-if-not 'oo + #'(lambda (x) + (or (list x) + (symbolp x))) + (list 'a 'b 'c (list 3 (list 4) 0))) + (a b c (3 (4) 0))) + +(my-assert + (subst 'a 'b (list 'u 'b (list 'b) 'c) + :test-not (lambda (x y) + (not (eql x y))) + :key (lambda (u) + (when (listp u) + (car u)))) + (u . a)) + +(my-assert + (subst-if 'nummmer + 'numberp + (list (list 'a (list 7 (list 'v 6))))) + + ((a (nummmer (v nummmer))))) + +(my-assert + (subst-if-not 'nummmer + #'(lambda (x) + (or (listp x) + (numberp x))) + (list (list 'a (list 7 (list 'v 6))))) + ((nummmer (7 (nummmer 6))))) + +(my-assert + (nsublis (list (cons (list 'a) 'uu) + (cons 'a 'ii)) + (list 'i (list 'a) 'a) + :test + (lambda (x y) + (when (listp y) + (eql x (car y))))) + #+(or xcl allegro ecls) (i ii . ii) ; x aus der aliste, y ein blatt des baumes + #+(or clisp cmu sbcl lucid) (i (uu) uu) ; x ein blatt, y aus der aliste + #-(or xcl clisp cmu sbcl lucid allegro ecls) unknown) + +(my-assert + (SUBLIS (QUOTE (((A) . UU) (A . II))) + (QUOTE (I (A) A)) + :TEST (LAMBDA (X Y) + (IF (LISTP Y) (EQL X (CAR Y))))) + #+nil + + (sublis (list (list (cons (list 'a) 'uu) (cons 'a 'ii))) + (list 'i (list 'a) 'a) + :test (lambda (x y) + (when (listp y) + (eql x (car y))))) + #+(or xcl allegro lucid ecls) (i ii . ii) ; x aus der aliste, y ein blatt des baumes + #+(or clisp cmu sbcl sbcl) (i (uu) uu) ; x ein blatt, y aus der aliste + #-(or xcl clisp cmu sbcl lucid allegro ecls) unknown) + +(my-assert + (member 'A + (list (list 'A) + (list 'B) + (list 'A) + (list 'C)) + :key + 'car) + ((a) (b) (a) (c))) + +(my-assert + (member-if 'numberp + (list (list 'a) + (list 'b) + (list 3) + (list 'c)) + :key 'car) + + ((3) (c))) + +(my-assert + (member-if-not 'numberp + (list (list 8) + (list 'a) + (list 'b) + (list 3) + (list 'c)) + :key 'car) + ((a) (b) (3) (c))) + +(my-assert + (tailp (cddr (setq xx (list 'u 'i 'a 'b))) xx) + t) + +(unintern 'xx) + +(my-assert + (tailp 'd (append (list 'a 'b 'c) 'd)) + t) + +(my-assert + (adjoin 'a + (list (list 'a) + 'b + 'c) + :test 'equal) + (a (a) b c)) + +(my-assert + (nunion (list 'a 'b 'c 'd) + (list 'u 'i 'b 'a)) + #+xcl (a b c d u i) + #+(or ecls clisp) (c d u i b a) + #+(or allegro cmu sbcl) (d c u i b a) + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (union (list 'a 'b 'c 'd) + (list 'a 'd 'i 'v)) + #+xcl (v i a b c d) + #+(or ecls clisp) (b c a d i v) + #+(or allegro cmu sbcl) (c b a d i v) + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (intersection (list (list 'a 1) + (list 'a 2) + (list 'a 3)) + (list (list 'a 4) + (list 'a 2) + (list 'b 6) + (list 'c 7)) + :test 'equal) + ((a 2))) + +(my-assert + (nintersection (list 'a 'b 'c 'd) + (list 'c 'd 'e 'f 'g) + :test-not (quote eql)) + #-(or allegro cmu sbcl sbcl) (a b c d) + #+(or allegro cmu sbcl sbcl) (d c b a)) + +(my-assert + (nset-difference (list 'a 'b 'c 'd) + (list 'i 'j 'c)) + #-(or allegro cmu sbcl sbcl) (a b d) + #+(or allegro cmu sbcl sbcl) (d b a)) + +(my-assert + (nset-exclusive-or (list 'a 'b 'c) + (list 'i 'a 'd 'c)) + (b i d)) + +(my-assert + (set-difference (list 'anton 'berta 'auto 'berlin) + (list 'amerilla) + :test (lambda (x y) + (eql (elt (symbol-name x) 0) + (elt (symbol-name y) 0)))) + #+(or xcl allegro cmu sbcl sbcl) (berlin berta) + #+(or clisp akcl ecls) (berta berlin) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (set-exclusive-or (list 'anton 'anna 'emil) + (list 'berta 'auto 'august) + :test (lambda (x y) + (eql (elt (symbol-name x) 0) + (elt (symbol-name y) 0)))) + #-(or allegro cmu sbcl) (emil berta) + #+(or allegro cmu sbcl) (berta emil)) + +(my-assert + (subsetp (list 'a 'b) (list 'b 'a 'u 'i 'c 'd)) + t) + +(my-assert + (acons 'a 'b (list (cons 'c 'd))) + ((a . b) (c . d))) + +(my-assert + (acons 'a 'b nil) + ((a . b))) + +(my-assert + (assoc 'a (list (list 'b 'c) + 'a + (list (list 'a) 'u) + (list 'a 'i)) + :test-not (lambda (x y) + (when (atom y) + (eql y x)))) + #+allegro error + #-allegro (b c)) + +(my-assert + (assoc-if 'symbolp + (list (cons 'a 3) + (cons 3 'a))) + (a . 3)) + +(my-assert + (assoc-if-not 'numberp (list (cons 'a 3) + (cons 3 'a))) + (a . 3)) + +(my-assert + (pairlis (list 'a 'b 'c) (list 1 2 3)) + ((c . 3) (b . 2) (a . 1))) + +(my-assert + (rassoc 'a (list (cons 1 'b) (cons 2 'a))) + (2 . a)) + +(my-assert + (rassoc-if 'symbolp + (list (cons 1 3) (cons 2 'a))) + (2 . a)) + +(my-assert + (rassoc-if-not 'symbolp + (list (cons 1 3) (cons 2 'a))) + (1 . 3)) + +;; kap 16 hash-tabellen +;; ---------------------------------------------------------------------------- + +(my-assert + (hash-table-p (make-hash-table :test #'eql + :rehash-size 2 + :size 20)) + t) + +(my-assert + (hash-table-p (make-hash-table :test #'eql + :rehash-size 1.1 + :size 20)) + t) +;; clrhash, gethash, hash-table-count, maphash, remhash, sxhash, + +;; /body/mac_with-hash_ble-iterator.html +(my-assert + (defun test-hash-table-iterator (hash-table) + (let ((all-entries '()) + (generated-entries '()) + (unique (list nil))) + (maphash #'(lambda (key value) + (push (list key value) + all-entries)) + hash-table) + (with-hash-table-iterator + (generator-fn hash-table) + (loop + (multiple-value-bind (more? key value) + (generator-fn) + (unless more? (return)) + (unless (eql value (gethash key hash-table unique)) + (error "Key ~S not found for value ~S" key value)) + (push (list key value) generated-entries)))) + (unless (= (length all-entries) + (length generated-entries) + (length (union all-entries + generated-entries + :key #'car + :test (hash-table-test hash-table)))) + (error "Generated entries and Maphash entries don't correspond")) + t)) + test-hash-table-iterator) + +(my-assert + (let ((tab (make-hash-table :test #'equal))) + (setf (gethash "Richard" tab) "Gabriel") + (setf (gethash "Bruno" tab) "Haible") + (setf (gethash "Michael" tab) "Stoll") + (setf (gethash "Linus" tab) "Torvalds") + (setf (gethash "Richard" tab) "Stallman") + (test-hash-table-iterator tab) + ) + t) + +;; kap 17 felder +;; ---------------------------------------------------------------------------- + +;; make-array, vector, aref, svref, array-element-type, array-rank, +;; array-dimension, array-dimensions, array-total-size, array-in-bounds-p, +;; array-row-major-index, adjustable-array-p, + +;; array-rank-limit, array-dimension-limit, array-total-size-limit, + + +;; bit, sbit, bit-and, bit-andc1, bit-andc2, bit-eqv, bit-ior, bit-nand, +;;; bit-nor, bit-not, bit-orc1, bit-orc2, bit-xor, + +;; array-has-fill-pointer-p, fill-pointer, vector-pop, vector-push, +;; vector-push-extend, adjust-array, + +;; kap 18 strings +;; ---------------------------------------------------------------------------- + +;; char, schar, string=, string-equal, string/=, string<, string<=, string>, + +;; string>=, string-greaterp, string-lessp, string-not-equal, +;; string-not-greaterp, string-not-lessp, make-string, string-left-trim, + +;; string-right-trim, string-trim, string-upcase, string-capitalize, + +;; string-downcase, nstring-capitalize, nstring-downcase, nstring-upcase, +;; string, + +;; kap 19 strukturen +;; ---------------------------------------------------------------------------- + +;; defstruct, + +(my-assert + (defstruct (ice-cream-factory + (:constructor make-factory) + (:constructor fabricate-factory + (&key (capacity 5) + location + (local-flavors + (case location + ((hawaii) '(pineapple macadamia guava)) + ((massachusetts) '(lobster baked-bean)) + ((california) '(ginger lotus avocado bean-sprout garlic)) + ((texas) '(jalapeno barbecue)))) + (flavors + (subseq (append local-flavors + '(vanilla chocolate strawberry pistachio + maple-walnut peppermint)) + 0 capacity))))) + (capacity 3) + (flavors '(vanilla chocolate strawberry mango))) + ice-cream-factory) + +(my-assert + (let ((houston (fabricate-factory :capacity 4 :location 'texas))) + (ice-cream-factory-flavors houston)) + (jalapeno barbecue vanilla chocolate)) + +(my-assert + (let ((cambridge (fabricate-factory :location 'massachusetts))) + (ice-cream-factory-flavors cambridge)) + (lobster baked-bean vanilla chocolate strawberry)) + +(my-assert + (let ((seattle (fabricate-factory :local-flavors '(salmon)))) + (ice-cream-factory-flavors seattle)) + (salmon vanilla chocolate strawberry pistachio)) + +(my-assert + (let ((wheaton (fabricate-factory :capacity 4 :location 'illinois))) + (ice-cream-factory-flavors wheaton)) + (vanilla chocolate strawberry pistachio)) + +(my-assert + (let ((pittsburgh (fabricate-factory :capacity 4))) + (ice-cream-factory-flavors pittsburgh)) + (vanilla chocolate strawberry pistachio)) + +(my-assert + (let ((cleveland (make-factory :capacity 4))) + (ice-cream-factory-flavors cleveland)) + (vanilla chocolate strawberry mango)) + +;; kap 20 eval +;; ---------------------------------------------------------------------------- + +;; eval, evalhook, *evalhook*, applyhook, *applyhook*, + +(my-assert + (constantp -5) + t) + +(my-assert + (constantp (read-from-string "1.0e30")) + t) + +;; kap 21 streams +;; ---------------------------------------------------------------------------- + +;; make-synonym-stream, make-broadcast-stream, make-concatenated-stream, +;; make-two-way-stream, make-echo-stream, make-string-input-stream, +;; make-string-output-stream, get-output-stream-string, with-input-from-string, +;; with-open-stream, with-output-to-string, + +(my-assert + (streamp *standard-input*) + t) + +(my-assert + (input-stream-p *terminal-io*) + t) + +;; output-stream-p, stream-element-type, close, + +;; kap 22 ein- und ausgabe +;; ---------------------------------------------------------------------------- + +(my-assert + (readtablep *readtable*) + t) + +(my-assert + (readtablep 'progn) + nil) + +;; copy-readtable, read, *read-base*, read-byte, read-char, read-char-no-hang, + +;; *read-default-float-format*, read-delimited-list, read-from-string, read-line, +;; read-preserving-whitespace, *read-suppress*, *readtable*, unread-char, + +;; get-dispatch-macro-character, get-macro-character, +;; set-dispatch-macro-character, set-macro-character, set-syntax-from-char, +;; make-dispatch-macro-character, + +(my-assert + (get-dispatch-macro-character #\# #\0) + nil) + +;; pprint, prin1, prin1-to-string, princ, princ-to-string, print, *print-array*, +;; *print-base*, *print-case*, *print-circle*, *print-escape*, *print-gensym*, + +;; *print-length*, *print-level*, *print-pretty*, *print-radix*, + +;; peek-char, listen, clear-input, clear-output, parse-integer, + +;; write, write-byte, write-char, write-line, write-string, write-to-string, +;; y-or-n-p, yes-or-no-p, + +;; terpri, finish-output, force-output, format, fresh-line, + +;; kap 23 file-interface +;; ---------------------------------------------------------------------------- + +;; pathname, truename, parse-namestring, merge-pathnames, +;; *default-pathname-defaults*, make-pathname, pathnamep, pathname-device, +;; pathname-directory, pathname-host, pathname-name, pathname-type, +;; pathname-version, namestring, file-namestring, directory-namestring, + +;; host-namestring, enough-namestring, user-homedir-pathname, open, +;; with-open-file, rename-file, delete-file, probe-file, file-write-date, + +;; file-author, file-length, file-position, load, *load-verbose*, directory + +;; kap 24 fehler +;; ---------------------------------------------------------------------------- + +;; cerror, error, *break-on-warnings*, warn, break, check-type, assert, etypecase, +;; ecase, ctypecase, ccase + +;; kap 25 erweiterungen +;; ---------------------------------------------------------------------------- + +;; compile, disassemble, compile-file, documentation, trace, untrace, step, time, +;; describe, inspect, room, ed, dribble, apropos, apropos-list, +;; get-decoded-time, get-internal-real-time, get-internal-run-time, +;; get-universal-time, decode-universal-time, encode-universal-time, + +;; internal-time-units-per-second, sleep, lisp-implementation-type, +;; lisp-implementation-version, machine-instance, machine-type, machine-version, + +;; software-type, software-version, short-site-name, long-site-name, *features*, +;; identity + +;; kap i systeminterne praedikate +;; ---------------------------------------------------------------------------- +;; ? (sequencep (type-specifier-p (bit-array-p +;; ? (adjustable-vector-with-fill-pointer-p (alistp (declaration-specifier-p + + +(my-assert + #-sbcl + (sys::fixnump 10) ;? + #+sbcl + (sb-kernel:fixnump 10) ;? + t) ;? + +;; kap ii systeminterne atome +;; ---------------------------------------------------------------------------- + +;; case-every, comment, cond-every, displace, return, return-from, access, boole, +;; call-arguments-limit, defun, errset, *errset*, *macroexpand-hook*, *package*, +;; *random-state*, *save-old-definition-when-redefined*, diff --git a/src/ansi-tests/array.lisp b/src/ansi-tests/array.lisp new file mode 100644 index 000000000..73f794678 --- /dev/null +++ b/src/ansi-tests/array.lisp @@ -0,0 +1,1006 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +;;erzeuge ein feld mit doppeltgenauen zahlen + +(my-assert + (setq da1 + (make-array + (list 4 2 3) + :initial-contents + (list + (list (list 1.0d0 2.0d0 3.0d0) + (list 4.0d0 5.0d0 6.0d0)) + (list (list 7.0d0 8.0d0 9.0d0) + (list 10.0d0 11.0d0 12.0d0)) + (list (list 13.0d0 14.0d0 15.0d0) + (list 16.0d0 17.0d0 18.0d0)) + (list (list 19.0d0 20.0d0 21.0d0) + (list 22.0d0 23.0d0 24.0d0))) + :element-type + (quote double-float))) + #3a(((1.0d0 2.0d0 3.0d0) (4.0d0 5.0d0 6.0d0)) + ((7.0d0 8.0d0 9.0d0) (10.0d0 11.0d0 12.0d0)) + ((13.0d0 14.0d0 15.0d0)(16.0d0 17.0d0 18.0d0)) + ((19.0d0 20.0d0 21.0d0)(22.0d0 23.0d0 24.0d0)))) + +(my-assert + (aref da1 0 0 0) + 1.0d0) + +(my-assert + (aref da1 0 0 1) + 2.0d0) + +(my-assert + (aref da1 0 0 2) + 3.0d0) + +(my-assert + (aref da1 0 1 0) + 4.0d0) + +(my-assert + (aref da1 0 1 1) + 5.0d0) + +(my-assert + (aref da1 0 1 2) + 6.0d0) + +(my-assert + (aref da1 1 0 0) + 7.0d0) + +(my-assert + (aref da1 1 0 1) + 8.0d0) + +(my-assert + (aref da1 1 0 2) + 9.0d0) + +(my-assert + (aref da1 1 1 0) + 10.0d0) + +(my-assert + (aref da1 1 1 1) + 11.0d0) + +(my-assert + (aref da1 1 1 2) + 12.0d0) + +(my-assert + (aref da1 2 0 0) + 13.0d0) + +(my-assert + (aref da1 2 0 1) + 14.0d0) + +(my-assert + (aref da1 2 0 2) + 15.0d0) + +(my-assert + (aref da1 2 1 0) + 16.0d0) + +(my-assert + (aref da1 2 1 1) + 17.0d0) + +(my-assert + (aref da1 2 1 2) + 18.0d0) + +(my-assert + (aref da1 3 0 0) + 19.0d0) + +(my-assert + (aref da1 3 0 1) + 20.0d0) + +(my-assert + (aref da1 3 0 2) + 21.0d0) + +(my-assert + (aref da1 3 1 0) + 22.0d0) + +(my-assert + (aref da1 3 1 1) + 23.0d0) + +(my-assert + (aref da1 3 1 1) + 23.0d0) + +;;erzeuge ein feld mit einfachgenauen zahlen + +(my-assert + (setq fa1 + (make-array + (list 4 2 3) + :initial-contents + (list + (list (list 1.0d0 2.0d0 3.0d0) + (list 4.0d0 5.0d0 6.0d0)) + (list (list 7.0d0 8.0d0 9.0d0) + (list 10.0d0 11.0d0 12.0d0)) + (list (list 13.0d0 14.0d0 15.0d0) + (list 16.0d0 17.0d0 18.0d0)) + (list (list 19.0d0 20.0d0 21.0d0) + (list 22.0d0 23.0d0 24.0d0))) + :element-type 'double-float)) + #3a(((1.0 2.0 3.0)(4.0 5.0 6.0)) + ((7.0 8.0 9.0)(10.0 11.0 12.0)) + ((13.0 14.0 15.0)(16.0 17.0 18.0)) + ((19.0 20.0 21.0)(22.0 23.0 24.0)))) + +(my-assert + (aref fa1 0 0 0) + 1.0) + +(my-assert + (aref fa1 0 0 1) + 2.0) + +(my-assert + (aref fa1 0 0 2) + 3.0) + +(my-assert + (aref fa1 0 1 0) + 4.0) + +(my-assert + (aref fa1 0 1 1) + 5.0) + +(my-assert + (aref fa1 0 1 2) + 6.0) + +(my-assert + (aref fa1 1 0 0) + 7.0) + +(my-assert + (aref fa1 1 0 1) + 8.0) + +(my-assert + (aref fa1 1 0 2) + 9.0) + +(my-assert + (aref fa1 1 1 0) + 10.0) + +(my-assert + (aref fa1 1 1 1) + 11.0) + +(my-assert + (aref fa1 1 1 2) + 12.0) + +(my-assert + (aref fa1 2 0 0) 13.0) + +(my-assert + (aref fa1 2 0 1) + 14.0) + +(my-assert + (aref fa1 2 0 2) + 15.0) + +(my-assert + (aref fa1 2 1 0) 16.0) + +(my-assert + (aref fa1 2 1 1) + 17.0) + +(my-assert + (aref fa1 2 1 2) + 18.0) + +(my-assert + (aref fa1 3 0 0) + 19.0) + +(my-assert + (aref fa1 3 0 1) + 20.0) + +(my-assert + (aref fa1 3 0 2) + 21.0) + +(my-assert + (aref fa1 3 1 0) + 22.0) + +(my-assert + (aref fa1 3 1 1) + 23.0) + +(my-assert + (aref fa1 3 1 1) + 23.0) + + +;; limits fuer felder + +(my-assert + (let ((s (prin1-to-string array-rank-limit ))) + (or #+xcl (equal s "256") + #+clisp (equal s "4294967296") + #+clisp (equal s "65536") + #+akcl (equal s "64") + #+gcl (equal s "63") + #+allegro (equal s "65536") + #+(or cmu sbcl) (equal s "65529") + #+ecls (equal s "64") + #-(or xcl clisp akcl allegro cmu sbcl ecls) "unknown" + ) ) + t) + +(my-assert + (let ((s (prin1-to-string array-dimension-limit ))) + (or #+xcl (equal s "17920") + #+akcl (equal s "16777216") + #+gcl (equal s "2147483647") + #+clisp (equal s (prin1-to-string (1+ most-positive-fixnum))) + #+allegro (equal s "16777216") + #+(or cmu sbcl) (equal s "536870911") + #+ecls (equal s "16777216") + #-(or xcl clisp akcl allegro cmu sbcl ecls) "unknown" + ) ) + t) + +(my-assert + (let ((s (prin1-to-string array-total-size-limit ))) + (or #+xcl (equal s "17920") + #+akcl (equal s "16777216") + #+clisp (equal s (prin1-to-string (1+ most-positive-fixnum))) + #+allegro (equal s "16777216") + #+(or cmu sbcl) (equal s "536870911") + #+ecls (equal s "16777216") + #-(or xcl clisp akcl allegro cmu sbcl ecls) "unknown" + ) ) + t) + +;;erzeuge einen einfachen (simple) vector + +(my-assert + (equalp (setq sv (vector (quote a) (quote b) (quote c) 1.0s0 3.7d0 + 4.1)) + #(a b c 1.0s0 3.7d0 4.1)) t) + +(my-assert + (svref sv 0) a) + +(my-assert + (svref sv 1) b) + +(my-assert + (svref sv 2) c) + +(my-assert + (svref sv 3) 1.0s0) + +(my-assert + (svref sv 4) 3.7d0) + +;;pruefe setzen eines elements + +(my-assert + (setf (svref sv 0) (quote test)) test) + +(my-assert + (equalp sv #(test b c 1.0s0 3.7d0 4.1)) t) + +;;test array-element-typ ... da2 nicht def. + +(my-assert + (array-element-type sv) t) + +(unintern 'sv) + +(my-assert + (array-element-type da1) + #+(or xcl allegro cmu sbcl) double-float + #+clisp t + #+(or akcl ecls) long-float + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +;;test rang + +(my-assert + (array-rank da1) 3) + +(my-assert + (array-rank fa1) 3) + +(unintern 'fa1) + +;;test der einzelnen dimensionen + +(my-assert + (array-dimension da1 0) 4) + +(my-assert + (array-dimension da1 1) 2) + +(my-assert + (array-dimension da1 2) 3) + +(my-assert + (array-dimension da1 3) error) + +(unintern 'da1) +;;erzeuge ein 0-dim. feld (pseudoscalar) mit inhalt mod 5 + +(my-assert + (progn + (setq zero + (make-array (quote nil) + :element-type '(mod 5))) + t) + t) + +(my-assert + (array-rank zero) 0) + +(my-assert + (setf (aref zero) 4) 4) + +(my-assert + (setf (aref zero) 1.0) + #+(or xcl clisp akcl allegro cmu sbcl ecls) type-error + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(unintern 'zero) + +;;erzeuge ein 3-dim gen. feld + +(my-assert + (setq a1 + (make-array (list 4 2 3) + :initial-contents + (list + (list (list 'a 'b 'c) + (list 1 2 3)) + (list (list 'd 'e 'f) + (list 3 1 2)) + (list (list 'g 'h 'i) + (list 2 3 1)) + (list (list 'j 'k 'l) + (list 0 0 0))))) + #3a(((a b c)(1 2 3)) + ((d e f)(3 1 2)) + ((g h i)(2 3 1)) + ((j k l)(0 0 0)))) + +(my-assert + (aref a1 0 0 0) a) + +(my-assert + (aref a1 0 0 1) b) + +(my-assert + (aref a1 0 0 2) c) + +(my-assert + (aref a1 0 1 0) 1) + +(my-assert + (aref a1 0 1 1) 2) + +(my-assert + (aref a1 0 1 2) 3) + +(my-assert + (aref a1 1 0 0) d) + +(my-assert + (aref a1 1 0 1) e) + +(my-assert + (aref a1 1 0 2) f) + +(my-assert + (aref a1 1 1 0) 3) + +(my-assert + (aref a1 1 1 1) 1) + +(my-assert + (aref a1 1 1 2) 2) + +(my-assert + (aref a1 2 0 0) g) + +(my-assert + (aref a1 2 0 1) h) + +(my-assert + (aref a1 2 0 2) i) + +(my-assert + (aref a1 2 1 0) 2) + +(my-assert + (aref a1 2 1 1) 3) + +(my-assert + (aref a1 2 1 2) 1) + +(my-assert + (aref a1 3 0 0) j) + +(my-assert + (aref a1 3 0 1) k) + +(my-assert + (aref a1 3 0 2) l) + +(my-assert + (aref a1 3 1 0) 0) + +(my-assert + (aref a1 3 1 1) 0) + +(my-assert + (aref a1 3 1 1) 0) + +(unintern 'a1) + +;;erzeuge ein 2-dim adj.feld, das ueberlagert wird + +(my-assert + (progn (setq m (make-array (list 4 4) + :adjustable t + :initial-contents + (list + (list 'alpha 'beta 'gamma 'delta) + (list 'epsilon 'zeta 'eta 'theta) + (list 'iota 'kappa 'lambda 'mu) + (list 'nu 'xi 'omicron 'pi)))) + t) + t) + +(my-assert + (aref m 0 0) alpha) + +(my-assert + (aref m 0 1) beta) + +(my-assert + (aref m 0 2) gamma) + +(my-assert + (aref m 0 3) delta) + +(my-assert + (aref m 1 0) epsilon) + +(my-assert + (aref m 1 1) zeta) + +(my-assert + (aref m 1 2) eta) + +(my-assert + (aref m 1 3) theta) + +(my-assert + (aref m 2 0) iota) + +(my-assert + (aref m 2 1) kappa) + +(my-assert + (aref m 2 2) lambda) + +(my-assert + (aref m 2 3) mu) + +(my-assert + (aref m 3 0) nu) + +(my-assert + (aref m 3 1) xi) + +(my-assert + (aref m 3 2) omicron) + +(my-assert + (aref m 3 3) pi) + +;;erzeuge ueberl. der zeilen + +(my-assert + (equalp (setq md0 (make-array 4 :displaced-to m)) #(alpha beta gamma + delta)) t) + +(my-assert + (equalp (setq md1 (make-array 4 :displaced-to m :displaced-index-offset4)) + #(epsilon zeta eta theta)) t) + + +(my-assert + (equalp (setq md2 (make-array 4 :displaced-to m :displaced-index-offset8)) + #(iota kappa lambda mu)) t) + + +(unintern 'md0) +(unintern 'md1) +(unintern 'md2) + + +;;adjustiere feld m + +(my-assert + (progn (adjust-array m (quote (3 5)) :initial-element (quote baz)) + t) t) + +(my-assert + (aref m 0 0) alpha) + +(my-assert + (aref m 0 1) beta) + +(my-assert + (aref m 0 2) gamma) + +(my-assert + (aref m 0 3) delta) + +(my-assert + (aref m 0 4) baz) + +(my-assert + (aref m 1 0) epsilon) + +(my-assert + (aref m 1 1) zeta) + +(my-assert + (aref m 1 2) eta) + +(my-assert + (aref m 1 3) theta) + +(my-assert + (aref m 1 4) baz) + +(my-assert + (aref m 2 0) iota) + +(my-assert + (aref m 2 1) kappa) + +(my-assert + (aref m 2 2) lambda) + +(unintern 'm) + +;;teste zusammenspiel der schluesselworte + +(my-assert + (progn + (setq dv (make-array 10 :element-type (quote double-float) + :initial-contents(quote (0.0d0 1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0)))) + t) + t) + +#| *************************************************************************** ; + + +(setq dve (make-array (quote (2 2)) :element-type (quote double-float) + + :initial-contents (quote ((1.0d0 2.0d0) (3.0d0 4.0d0 5.0d0))))) error + +(setq dve (make-array (quote (2 2)) :element-type (quote double-float) + + :initial-contents (quote + ((1.0d0 2.0d0) (3.0d0 4.0d0) :displaced-to dv :displaced-index-offset + 8)))) error + +(setq dve (make-array (quote (2 2)) :element-type (quote double-float) + + :initial-contents (quote ((1.0d0 2.0d0) (3.0d0 4.0d0))) :displaced-to + dv + :displaced-index-offset 8)) error + +(setq dve (make-array (quote (2 2)) :element-type (quote double-float) + + :displaced-to dv :displaced-index-offset 8)) error + +***************************************************************************|# + +(my-assert + (aref dv 0) 0.0d0) + +(my-assert + (aref dv 1) 1.0d0) + +(my-assert + (aref dv 2) 2.0d0) + +(my-assert + (aref dv 3) 3.0d0) + +(my-assert + (aref dv 4) 4.0d0) + +(my-assert + (aref dv 5) 5.0d0) + +(my-assert + (aref dv 6) 6.0d0) + +(my-assert + (aref dv 7) 7.0d0) + +(my-assert + (aref dv 8) 8.0d0) + +(my-assert + (aref dv 9) 9.0d0) + +(my-assert + (setf (aref dv 5) -5.0d0) -5.0d0) + +(unintern 'dv) + +;;definiere testfkt fuer indices + +(my-assert + (defun array-index-test (a &rest subs) (unless + (apply (function array-in-bounds-p) a subs) + (return-from array-index-test (quote error))) (= + (apply (function array-row-major-index) a subs) (apply (function +) + (maplist + (function (lambda (x y) (* (car x) (apply (function *) (cdr y))))) + subs + (array-dimensions a))))) array-index-test) + +(my-assert + (array-index-test (make-array (quote (5 4 3 2 1))) 4 2 2 1 0) t) + +(my-assert + (array-index-test (make-array (quote (5 4 3 2 1))) 3 4 2 1 2) error) + +;;test bitfelder + +(my-assert + (setq bvzero (make-array 100 :element-type (quote bit) :initial-element + 0)) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +(my-assert + (setq bvone (make-array 100 :element-type (quote bit) :initial-element + 1)) + #*1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111) + +(my-assert + (setq bv3 (make-array 100 :element-type (quote bit) :initial-element + 0)) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +(my-assert + (setq bv2 (make-array 100 :element-type (quote bit) :initial-element + 0)) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +(my-assert + (setq bv1 (make-array 100 :element-type (quote bit) :initial-element + 0)) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +;;setze bitfelder + +(my-assert + (dotimes (i 50 bv1) (setf (sbit bv1 (* i 2)) 1)) + #*1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010) + +(my-assert + (dotimes (i 50 bv2) (setf (bit bv2 (* i 2)) 1)) + #*1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010) + +(my-assert + (equalp bv1 bv2) t) + +(my-assert + (dotimes (i 25 bv3) + (setf (sbit bv3 (* i 4)) + 1)) + #*1000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000) + +(my-assert + (bit-and bv1 bv3) + #*1000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000) + +(my-assert + (bit-ior bv1 bv3) + #*1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010) + +(my-assert + (bit-xor bv1 bv3) + #*0010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010) + +(my-assert + (bit-eqv bv1 bv3) + #*1101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101) + +(my-assert + (bit-nand bv1 bv3) + #*0111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111) + +(my-assert + (bit-andc1 bv1 bv3) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +(my-assert + (bit-andc2 bv1 bv3) + #*0010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010) + +(my-assert + (bit-orc1 bv1 bv3) + #*1101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101) + +(my-assert + (bit-orc2 bv1 bv3) + #*1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111) + +(my-assert + (bit-not bv1) + #*0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101) + +(my-assert + (bit-not bvzero) + #*1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111) + +(my-assert + (bit-not bvone) + #*0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) + +(unintern 'bv1) +(unintern 'bv2) +(unintern 'bv3) +(unintern 'bvzero) +(unintern 'bvone) + +;;teste operationen mit fillpointern + +(my-assert + (make-array (quote (3 4 5)) :fill-pointer t) error) + +(my-assert + (equalp (make-array 5 :fill-pointer 5) + #+(or xcl cmu sbcl) + #(0 0 0 0 0) + #-(or xcl cmu sbcl) + #(nil nil nil nil nil)) + t) + +(my-assert + (make-array 5 :fill-pointer -5) error) + +;;allgem. vector mit fillpointer + +(my-assert + (progn (setq vmf (make-array 5 :fill-pointer 0)) t) t) + +(my-assert + (fill-pointer vmf) 0) + +(my-assert + (vector-push (quote a) vmf) 0) + +(my-assert + (fill-pointer vmf) 1) + +(my-assert + (vector-push (quote b) vmf) 1) + +(my-assert + (vector-push (quote c) vmf) 2) + +(my-assert + (vector-push (quote d) vmf) 3) + +(my-assert + (vector-push (quote e) vmf) 4) + +(my-assert + (vector-push (quote voll) vmf) nil) + +(my-assert + (vector-pop vmf) e) + +(my-assert + (vector-pop vmf) d) + +(my-assert + (vector-pop vmf) c) + +(my-assert + (vector-pop vmf) b) + +(my-assert + (vector-pop vmf) a) + +(my-assert + (vector-pop vmf) error) + +;;adjustabler allgem. vector mit fillpointer + +(unintern 'vmf) + +(my-assert + (progn (setq vmfa (make-array 5 :fill-pointer 0 :adjustable t)) t) + t) + +(my-assert + (fill-pointer vmfa) 0) + +(my-assert + (vector-push-extend (quote a) vmfa) 0) + +(my-assert + (fill-pointer vmfa) 1) + +(my-assert + (vector-push-extend (quote b) vmfa) 1) + +(my-assert + (vector-push-extend (quote c) vmfa) 2) + +(my-assert + (vector-push-extend (quote d) vmfa) 3) + +(my-assert + (vector-push-extend (quote e) vmfa) 4) + +(my-assert + (vector-push-extend (quote voll) vmfa) 5) + +(my-assert + (vector-pop vmfa) voll) + +(my-assert + (vector-pop vmfa) e) + +(my-assert + (vector-pop vmfa) d) + +(my-assert + (vector-pop vmfa) c) + +(my-assert + (vector-pop vmfa) b) + +(my-assert + (vector-pop vmfa) a) + +;;doppeltgen. vector mit fillpointer + +(unintern 'vmfa) + +(my-assert + (progn + (setq vmfd (make-array 5 :fill-pointer 0 :element-type (quote double-float))) + t) t) + +(my-assert + (fill-pointer vmfd) 0) + +(my-assert + (vector-push 0.0d0 vmfd) 0) + +(my-assert + (fill-pointer vmfd) 1) + +(my-assert + (vector-push 1.0d0 vmfd) 1) + +(my-assert + (vector-push 2.0d0 vmfd) 2) + +(my-assert + (vector-push 3.0d0 vmfd) 3) + +(my-assert + (vector-push 4.0d0 vmfd) 4) + +(my-assert + (vector-push 5.0d0 vmfd) nil) + +(my-assert + (vector-pop vmfd) 4.0d0) + +(my-assert + (vector-pop vmfd) 3.0d0) + +(my-assert + (vector-pop vmfd) 2.0d0) + +(my-assert + (vector-pop vmfd) 1.0d0) + +(my-assert + (vector-pop vmfd) 0.0d0) + +(my-assert + (vector-pop vmfd) error) + +;;doppeltgen. adjust. vector mit fillpointer + +(unintern 'vmfd) + +(my-assert + (progn (setq vmfad + (make-array 5 :fill-pointer 0 :element-type (quote double-float) :adjustable + t)) + t) t) + +(my-assert + (fill-pointer vmfad) 0) + +(my-assert + (vector-push-extend 0.0d0 vmfad) 0) + +(my-assert + (fill-pointer vmfad) 1) + +(my-assert + (vector-push-extend 1.0d0 vmfad) 1) + +(my-assert + (vector-push-extend 2.0d0 vmfad) 2) + +(my-assert + (vector-push-extend 3.0d0 vmfad) 3) + +(my-assert + (vector-push-extend 4.0d0 vmfad) 4) + +(my-assert + (vector-push-extend 5.0d0 vmfad) 5) + +(my-assert + (vector-pop vmfad) 5.0d0) + +(my-assert + (vector-pop vmfad) 4.0d0) + +(my-assert + (vector-pop vmfad) 3.0d0) + +(my-assert + (vector-pop vmfad) 2.0d0) + +(my-assert + (vector-pop vmfad) 1.0d0) + +(my-assert + (vector-pop vmfad) 0.0d0) + +(my-assert + (vector-push-extend 5.0s0 vmfad) + #+(or xcl gcl allegro cmu sbcl) error + #+(or clisp ecls (and akcl (not gcl))) 0 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(unintern 'vmfad) diff --git a/src/ansi-tests/backquot.lisp b/src/ansi-tests/backquot.lisp new file mode 100644 index 000000000..b28e82427 --- /dev/null +++ b/src/ansi-tests/backquot.lisp @@ -0,0 +1,34 @@ +;;; Based on 1.1.1.1 -*- mode: lisp -*- +;;; testen von backquote +(in-package :cl-user) + +(my-assert + (setf x (list 'a 'b 'c)) + (a b c)) + +(my-assert + `(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x) ,. x) + (X (A B C) A B C FOO B BAR (B C) BAZ B C A B C)) + +(my-assert + (read-from-string "`,@x") + ERROR) + +(my-assert + `(,x . ,x) ; = (append (list x) x) + ((a b c) a b c)) + + +(my-assert + (read-from-string "`(,x . ,@x)") + ERROR) + + +(my-assert + (read-from-string ",x") + ERROR) + +(my-assert + `#(1 2 3 4) + #(1 2 3 4)) + diff --git a/src/ansi-tests/characters.lisp b/src/ansi-tests/characters.lisp new file mode 100644 index 000000000..f1a1669d0 --- /dev/null +++ b/src/ansi-tests/characters.lisp @@ -0,0 +1,894 @@ +;;; based on v1.4 -*- mode: lisp -*- +(in-package :cl-user) + + +(my-assert + char-code-limit + #+xcl 128 + #+(or (and clisp (not unicode)) akcl sbcl cmu ecls) 256 + #+(or (and clisp unicode) allegro) 65536 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (standard-char-p #\a) + t) + +(my-assert + (standard-char-p #\$) + t) + +(my-assert + (standard-char-p #\.) + t) + +(my-assert + (standard-char-p #\A) + t) + +(my-assert + (standard-char-p 1) + type-error) + +(my-assert + (standard-char-p #\\) + t) + +(my-assert + (standard-char-p #\5) + t) + +(my-assert + (standard-char-p #\)) + t) + +(my-assert + (standard-char-p #\%) + t) + +(my-assert + (standard-char-p #\Backspace) + #+xcl t + #-xcl nil) + +(my-assert + (standard-char-p #\Page) + #+xcl t + #-xcl nil) + +(my-assert + (standard-char-p #\Return) + #+xcl t + #-xcl nil) + +(my-assert + (graphic-char-p #\a) + t) + +(my-assert + (graphic-char-p #\$) + t) + +(my-assert + (graphic-char-p #\.) + t) + +(my-assert + (graphic-char-p #\A) + t) + +(my-assert + (graphic-char-p 1) + type-error) + +(my-assert + (graphic-char-p #\\) + t) + +(my-assert + (graphic-char-p #\5) + t) + +(my-assert + (graphic-char-p #\)) + t) + +(my-assert + (graphic-char-p #\%) + t) + +(my-assert + (graphic-char-p #\Backspace) + nil) + +(my-assert + (graphic-char-p #\Page) + nil) + +(my-assert + (graphic-char-p #\Return) + nil) + +(my-assert + (characterp + #\a) + t) + +(my-assert + (characterp + #\$) + t) + +(my-assert + (characterp + #\.) + t) + +(my-assert + (characterp + #\A) + t) + +(my-assert + (characterp + #\\) + t) + +(my-assert + (characterp + #\5) + t) + +(my-assert + (characterp + #\)) + t) + +(my-assert + (characterp + #\%) + t) + +(my-assert + (characterp + #\Backspace) + t) + +(my-assert + (characterp + #\Page) + t) + +(my-assert + (characterp + #\Return) + t) + +(my-assert + (alpha-char-p #\a) + t) + +(my-assert + (alpha-char-p #\$) + nil) + +(my-assert + (alpha-char-p #\.) + nil) + +(my-assert + (alpha-char-p #\A) + t) + +(my-assert + (alpha-char-p 1) + type-error) + +(my-assert + (alpha-char-p #\\) + nil) + +(my-assert + (alpha-char-p #\5) + nil) + +(my-assert + (alpha-char-p #\)) + nil) + +(my-assert + (alpha-char-p #\%) + nil) + +(my-assert + (alpha-char-p #\Backspace) + nil) + +(my-assert + (alpha-char-p #\Page) + nil) + +(my-assert + (alpha-char-p #\Return) + nil) + +(my-assert + (upper-case-p #\a) + nil) + +(my-assert + (upper-case-p #\$) + nil) + +(my-assert + (upper-case-p #\.) + nil) + +(my-assert + (upper-case-p #\A) + t) + +(my-assert + (upper-case-p 1) + type-error) + +(my-assert + (upper-case-p #\\) + nil) + +(my-assert + (upper-case-p #\5) + nil) + +(my-assert + (upper-case-p #\)) + nil) + +(my-assert + (upper-case-p #\%) + nil) + +(my-assert + (upper-case-p #\Backspace) + nil) + +(my-assert + (upper-case-p #\Page) + nil) + +(my-assert + (upper-case-p #\Return) + nil) + +(my-assert + (lower-case-p #\a) + t) + +(my-assert + (lower-case-p #\$) + nil) + +(my-assert + (lower-case-p #\.) + nil) + +(my-assert + (lower-case-p #\A) + nil) + +(my-assert + (lower-case-p 1) + type-error) + +(my-assert + (lower-case-p #\\) + nil) + +(my-assert + (lower-case-p #\5) + nil) + +(my-assert + (lower-case-p #\)) + nil) + +(my-assert + (lower-case-p #\%) + nil) + +(my-assert + (lower-case-p #\Backspace) + nil) + +(my-assert + (lower-case-p #\Page) + nil) + +(my-assert + (lower-case-p #\Return) + nil) + +(my-assert + (both-case-p #\a) + t) + +(my-assert + (both-case-p #\$) + nil) + +(my-assert + (both-case-p #\.) + nil) + +(my-assert + (both-case-p #\A) + t) + +(my-assert + (both-case-p 1) + type-error) + +(my-assert + (both-case-p #\\) + nil) + +(my-assert + (both-case-p #\5) + nil) + +(my-assert + (both-case-p #\)) + nil) + +(my-assert + (both-case-p #\%) + nil) + +(my-assert + (both-case-p #\Backspace) + nil) + +(my-assert + (both-case-p #\Page) + nil) + +(my-assert + (both-case-p #\Return) + nil) + +(my-assert + (digit-char-p #\a) + nil) + +(my-assert + (digit-char-p #\$) + nil) + +(my-assert + (digit-char-p #\.) + nil) + +(my-assert + (digit-char-p #\A) + nil) + +(my-assert + (digit-char-p 1) + type-error) + +(my-assert + (digit-char-p #\\) + nil) + +(my-assert + (digit-char-p #\5) + 5) + +(my-assert + (digit-char-p #\)) + nil) + +(my-assert + (digit-char-p #\%) + nil) + +(my-assert + (digit-char-p #\Backspace) + nil) + +(my-assert + (digit-char-p #\Page) + nil) + +(my-assert + (digit-char-p #\Return) + nil) + +(my-assert + (digit-char-p #\5 4) + nil) + +(my-assert + (digit-char-p #\5 8) + 5) + +(my-assert + (digit-char-p #\E 16) + 14) + +(my-assert + (digit-char-p #\R 35) + 27) + +(my-assert + (digit-char-p #\5 4) + nil) + +(my-assert + (digit-char-p #\5 5) + nil) + +(my-assert + (digit-char-p #\5 6) + 5) + +(my-assert + (digit-char-p #\1 2) + 1) + +(my-assert + (alphanumericp #\a) + t) + +(my-assert + (alphanumericp #\$) + nil) + +(my-assert + (alphanumericp #\.) + nil) + +(my-assert + (alphanumericp #\A) + t) + +(my-assert + (alphanumericp 1) + type-error) + +(my-assert + (alphanumericp #\\) + nil) + +(my-assert + (alphanumericp #\5) + t) + +(my-assert + (alphanumericp #\)) + nil) + +(my-assert + (alphanumericp #\%) + nil) + +(my-assert + (alphanumericp #\Backspace) + nil) + +(my-assert + (alphanumericp #\Page) + nil) + +(my-assert + (alphanumericp #\Return) + nil) + +(my-assert + (alphanumericp #\5 4) + error) + +(my-assert + (alphanumericp #\5 8) + error) + +(my-assert + (alphanumericp #\E 16) + error) + +(my-assert + (alphanumericp #\R 35) + error) + +(my-assert + (char= #\d #\d) + t) + +(my-assert + (char/= #\d #\d) + nil) + +(my-assert + (char= #\d #\x) + nil) + +(my-assert + (char/= #\d #\x) + t) + +(my-assert + (char= #\d #\D) + nil) + +(my-assert + (char/= #\d #\D) + t) + +(my-assert + (char= #\d #\d #\d #\d) + t) + +(my-assert + (char/= #\d #\d #\d #\d) + nil) + +(my-assert + (char= #\d #\d #\x #\d) + nil) + +(my-assert + (char/= #\d #\d #\x #\d) + nil) + +(my-assert + (char= #\d #\y #\x #\c) + nil) + +(my-assert + (char/= #\d #\y #\x #\c) + t) + +(my-assert + (char= #\d #\c #\d) + nil) + +(my-assert + (char/= #\d #\c #\d) + nil) + +(my-assert + (char< #\d #\x) + t) + +(my-assert + (char<= #\d #\x) + t) + +(my-assert + (char< #\d #\d) + nil) + +(my-assert + (char<= #\d #\d) + t) + +(my-assert + (char< #\a #\e #\y #\z) + t) + +(my-assert + (char<= #\a #\e #\y #\z) + t) + +(my-assert + (char< #\a #\e #\e #\y) + nil) + +(my-assert + (char<= #\a #\e #\e #\y) + t) + +(my-assert + (char> #\e #\d) + t) + +(my-assert + (char>= #\e #\d) + t) + +(my-assert + (char> #\d #\c #\b #\a) + t) + +(my-assert + (char>= #\d #\c #\b #\a) + t) + +(my-assert + (char> #\d #\d #\b #\a) + nil) + +(my-assert + (char>= #\d #\d #\b #\a) + t) + +(my-assert + (char> #\e #\d #\b #\c #\a) + nil) + +(my-assert + (char>= #\e #\d #\b #\c #\a) + nil) + +(my-assert + (char> #\z #\A) + t) + +(my-assert + (char> #\Z #\a) + nil) + +(my-assert + (char< #\9 #\a) + t) + +(my-assert + (char> #\9 #\a) + nil) + +(my-assert + (char> #\z #\0) + t) + +(my-assert + (char< #\z #\0) + nil) + +(my-assert + (char-equal #\d #\d) + t) + +(my-assert + (char-not-equal #\d #\d) + nil) + +(my-assert + (char-equal #\d #\x) + nil) + +(my-assert + (char-not-equal #\d #\x) + t) + +(my-assert + (char-equal #\d #\D) + t) + +(my-assert + (char-not-equal #\d #\D) + nil) + +(my-assert + (char-equal #\d #\d #\d #\d) + t) + +(my-assert + (char-not-equal #\d #\d #\d #\d) + nil) + +(my-assert + (char-equal #\d #\d #\x #\d) + nil) + +(my-assert + (char-not-equal #\d #\d #\x #\d) + nil) + +(my-assert + (char-equal #\d #\y #\x #\c) + nil) + +(my-assert + (char-not-equal #\d #\y #\x #\c) + t) + +(my-assert + (char-equal #\d #\c #\d) + nil) + +(my-assert + (char-not-equal #\d #\c #\d) + nil) + +(my-assert + (char-lessp #\d #\x) + t) + +(my-assert + (char-not-greaterp #\d #\x) + t) + +(my-assert + (char-lessp #\d #\d) + nil) + +(my-assert + (char-not-greaterp #\d #\d) + t) + +(my-assert + (char-lessp #\a #\e #\y #\z) + t) + +(my-assert + (char-not-greaterp #\a #\e #\y #\z) + t) + +(my-assert + (char-lessp #\a #\e #\e #\y) + nil) + +(my-assert + (char-not-greaterp #\a #\e #\e #\y) + t) + +(my-assert + (char-greaterp #\e #\d) + t) + +(my-assert + (char-not-lessp #\e #\d) + t) + +(my-assert + (char-greaterp #\d #\c #\b #\a) + t) + +(my-assert + (char-not-lessp #\d #\c #\b #\a) + t) + +(my-assert + (char-greaterp #\d #\d #\b #\a) + nil) + +(my-assert + (char-not-lessp #\d #\d #\b #\a) + t) + +(my-assert + (char-greaterp #\e #\d #\b #\c #\a) + nil) + +(my-assert + (char-not-lessp #\e #\d #\b #\c #\a) + nil) + +(my-assert + (char-greaterp #\z #\A) + t) + +(my-assert + (char-greaterp #\Z #\a) + t) + +(my-assert + (char-lessp #\9 #\a) + t) + +(my-assert + (char-greaterp #\9 #\a) + nil) + +(my-assert + (char-greaterp #\z #\0) + t) + +(my-assert + (char-lessp #\z #\0) + nil) + +(my-assert + (char-equal #\A #\a) + t) + +(my-assert + (char-upcase #\a) + #\A) + +(my-assert + (char-upcase #\A) + #\A) + +(my-assert + (char-upcase #\5) + #\5) + +(my-assert + (char-upcase #\;) + #\;) + +(my-assert + (char-upcase #\=) + #\=) + +(my-assert + (char= (char-downcase (char-upcase #\x)) #\x) + t) + +(my-assert + (char-downcase #\A) + #\a) + +(my-assert + (char-downcase #\a) + #\a) + +(my-assert + (char-downcase #\%) + #\%) + +(my-assert + (char-downcase #\+) + #\+) + +(my-assert + (char-downcase #\-) + #\-) + +(my-assert + (char= (char-upcase (char-downcase #\X)) #\X) + t) + +(my-assert + (digit-char 7) + #\7) + +(my-assert + (digit-char 12) + nil) + +(my-assert + (digit-char 'a) + error) + +(my-assert + (digit-char 12 16) + #\C) + +(my-assert + (digit-char 6 2) + nil) + +(my-assert + (digit-char 1 2) + #\1) + +;; evan though char-*-bit are not in the ANSI CL standard, +;; they may be present as an extension + +;; (my-assert +;; char-control-bit +;; error) + +;; (my-assert +;; char-meta-bit +;; error) + +;; (my-assert +;; char-super-bit +;; error) + +;; (my-assert +;; char-hyper-bit +;; error) + +(my-assert + (char-name #\Space) + "Space") + +(my-assert + (char-name #\Newline) + #-cmu + "Newline" + #+cmu + "Linefeed") diff --git a/src/ansi-tests/clos.lisp b/src/ansi-tests/clos.lisp new file mode 100644 index 000000000..814be0647 --- /dev/null +++ b/src/ansi-tests/clos.lisp @@ -0,0 +1,468 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + + +#-(OR CMU SBCL) +(my-assert + (use-package "CLOS") + T) + +#+SBCL +(my-assert + (use-package "SB-PCL") + T) + +(my-assert + (unintern ') + T) + +(my-assert + (progn + (defclass () + ((x :initform 0 :accessor x-val :reader get-x :writer set-x :initarg :x) + (y :initform 1 :accessor y-val :reader get-y :writer set-y :initarg :y))) + ()) + NIL) + +(my-assert + (progn + (defclass () + ((z :initform 0 :accessor z-val :reader get-z :writer set-z :initarg :z))) + ()) + NIL) + +(my-assert + (defparameter a (make-instance (find-class ') :x 10)) + A) + +(my-assert + (x-val a) + 10) + +(my-assert + (y-val a) + 1) + +(my-assert + (setf (x-val a) 20) + 20) + +(my-assert + (x-val a) + 20) + +(my-assert + (get-x a) + 20) + +(my-assert + (set-x 10 a) + 10) + +(my-assert + (x-val a) + 10) + +(my-assert + (defparameter b (make-instance (find-class ') :x 10 :y 20 :z 30)) + B) + +(my-assert + (x-val b) + 10) + +(my-assert + (y-val b) + 20) + +(my-assert + (z-val b) + 30) + +(my-assert + (progn + (defgeneric f (x y) + (:method ((x t) (y t)) + (list x y))) + (defmethod f ((i integer) (j number)) + (+ i j)) + (defmethod f ((s1 string) (s2 string)) + (concatenate 'string s1 s2)) + ()) + NIL) + +(my-assert + (f t t) + (T T)) + +(my-assert + (f 2 3) + 5) + +(my-assert + (f 2 3.0) + 5.0) + +(my-assert + (f 2.0 3) + (2.0 3)) + +(my-assert + (f "ab" "cd") + "abcd") + +(my-assert + (f 1 "abc") + (1 "abc")) + +(my-assert + (progn + (defgeneric f (x y) + (:method ((x t) (y t)) + (list x y)) + (:method ((i number) (j integer)) + (list (call-next-method) (- i j))) + (:method ((i integer) (j number)) + (list (call-next-method) (+ i j)))) + ()) + NIL) + +(my-assert + (f 'x 'y) + (X Y)) + +(my-assert + (f 1 2) + (((1 2) -1) 3)) + +(my-assert + (f 1 2.0) + ((1 2.0) 3.0)) + +(my-assert + (f 1.0 2) + ((1.0 2) -1.0)) + +(my-assert + (progn + (defgeneric g (x) + (:method ((x null)) + (cons 'null (call-next-method))) + (:method ((x list)) + (if (next-method-p) + (cons 'list (call-next-method)) + '(list$))) + (:method ((x symbol)) + (if (next-method-p) + (cons 'symbol (call-next-method)) + '(symbol$)))) + ()) + NIL) + +(my-assert + (g 'x) + (SYMBOL$)) + +(my-assert + (g '(x)) + (LIST$)) + +(my-assert + (g '()) + (NULL SYMBOL LIST$) + "Class precedence list for NULL: + +null, symbol, list, sequence, t") + +(my-assert + (defvar hl) + HL) + +(my-assert + (progn + (defgeneric hgen (x) + (:method ((x integer)) + (setf hl (cons 'i-primary-1 hl)) + (call-next-method) + (setf hl (cons 'i-primary-2 hl))) + (:method :before ((x integer)) + (setf hl (cons 'i-before hl))) + (:method :after ((x integer)) + (setf hl (cons 'i-after hl))) + (:method :around ((x integer)) + (setf hl (cons 'i-around-1 hl)) + (call-next-method) + (setf hl (cons 'i-around-2 hl))) + (:method ((x number)) + (setf hl (cons 'n-primary-1 hl)) + (call-next-method) + (setf hl (cons 'n-primary-2 hl))) + (:method :before ((x number)) + (setf hl (cons 'n-before hl))) + (:method :after ((x number)) + (setf hl (cons 'n-after hl))) + (:method :around ((x number)) + (setf hl (cons 'n-around-1 hl)) + (call-next-method) + (setf hl (cons 'n-around-2 hl))) + (:method ((x t)) + (setf hl (cons 'innermost hl)))) + (defun h (x) + (setf hl '()) (hgen x) (reverse hl)) + ) + H) + +(my-assert + (h 'abc) + (INNERMOST)) + +(my-assert + (h 3.14) + (N-AROUND-1 N-BEFORE N-PRIMARY-1 INNERMOST N-PRIMARY-2 N-AFTER N-AROUND-2)) + +(my-assert + (h 3) + (I-AROUND-1 N-AROUND-1 I-BEFORE N-BEFORE I-PRIMARY-1 N-PRIMARY-1 INNERMOST + N-PRIMARY-2 I-PRIMARY-2 N-AFTER I-AFTER N-AROUND-2 I-AROUND-2 + )) + +(my-assert + (unintern ') + T) + +(my-assert + (progn + (defclass () + ((x :initform 0 :accessor x-val :initarg :x) + (y :initform 1 :accessor y-val :initarg :y))) + ()) + NIL) + +(my-assert + (defparameter a (make-instance (find-class ') :x 10)) + A) + +(my-assert + (defparameter b (make-instance (find-class ') :y 20 :x 10)) + B) + +(my-assert + (defparameter c (make-instance (find-class '))) + C) + +(my-assert + (x-val a) + 10) + +(my-assert + (y-val a) + 1) + +(my-assert + (x-val b) + 10) + +(my-assert + (y-val b) + 20) + +(my-assert + (x-val c) + 0) + +(my-assert + (y-val c) + 1) + +(my-assert + (unintern ') + T) + +(my-assert + (progn + (defclass () + ((x :initform 0 :accessor x-val :initarg :x) + (y :initform 1 :accessor y-val :initarg :y))) + (defmethod initialize-instance :after ((instance ) &rest initvalues) + (if (= (x-val instance) 0) + (setf (x-val instance) (y-val instance)))) + ()) + NIL) + +(my-assert + (x-val (make-instance (find-class '))) + 1) + +(my-assert + (x-val (make-instance (find-class ') :x 10)) + 10) + +(my-assert + (x-val (make-instance (find-class ') :y 20)) + 20) + +(my-assert + (x-val (make-instance (find-class ') :x 10 :y 20)) + 10) + +(my-assert + (unintern ') + T) + +(my-assert + (eq (class-of ()) (find-class 'null)) + T) + +(my-assert + (eq (class-of t) (find-class 'symbol)) + T) + +(my-assert + (eq (class-of 10) + (find-class #+(or ALLEGRO cmu sbcl) 'fixnum + #-(or ALLEGRO cmu sbcl) 'integer)) + T) + +(my-assert + (eq (class-of 10.0) + (find-class #+(or ALLEGRO cmu sbcl) 'single-float + #-(or ALLEGRO cmu sbcl) 'float)) + T) + +(my-assert + (eq (class-of '(a b)) + (find-class 'cons)) + T) + +(my-assert + (eq (class-of "abc") + (find-class #+(OR CMU SBCL) 'simple-string + #-(OR CMU SBCL) 'string)) + T) + +(my-assert + (eq (class-of '#(1 2)) + (find-class #+(OR CMU SBCL) 'simple-vector + #-(OR CMU SBCL) 'vector)) + T) + +(my-assert + (eq (class-of #'car) + (find-class 'function)) + T) + +(my-assert + (eq (class-of #'make-instance) + (find-class 'standard-generic-function)) + T) + +(my-assert + (eq (class-of '#2a((a) (b))) + (find-class #+(OR CMU SBCL) 'simple-array + #-(OR CMU SBCL) 'array)) + T) + +(my-assert + (eq (class-of *standard-input*) + (find-class 'stream)) + NIL) + +(my-assert + (eq (class-of (lambda (x) x)) + (find-class 'function)) + T + "lambda should return a function. + +a function is: +function n. 1. an object representing code, which can +be called with zero or more arguments, and which produces +zero or more values. 2. an object of type function. + +So class-of should return a function. Not?") + +(my-assert + (eq (class-of (find-class 't)) + (find-class 'built-in-class)) + T) + +(my-assert + (typep "abc" (find-class 't)) + T) + +(my-assert + (typep "abc" (find-class 'array)) + T) + +(my-assert + (typep "abc" (find-class 'vector)) + T) + +(my-assert + (typep "abc" (find-class 'string)) + T) + +(my-assert + (typep "abc" (find-class 'integer)) + NIL) + +(my-assert + (typep 3 (find-class 't)) + T) + +(my-assert + (typep 3 (find-class 'number)) + T) + +(my-assert + (typep 3 (find-class 'float)) + NIL) + +(my-assert + (typep 3 (find-class 'integer)) + T) + +(my-assert + (typep 3 (find-class 'string)) + NIL) + +(my-assert + (typep *standard-input* (find-class 'stream)) + T) + +#+(or clisp allegro cmu sbcl) +(my-assert + #+CLISP + (defun subclassp (class1 class2) + (clos::subclassp class1 class2) + ) + #+ALLEGRO + (defun subclassp (class1 class2) + (finalize-inheritance class1) + (not (null (member class2 (class-precedence-list class1)))) + ) + #+CMU + (defun subclassp (class1 class2) + (not (null (member (car (pcl:class-precedence-list class2)) + (pcl:class-precedence-list class1) + ) ) ) ) + #+sbcl + (defun subclassp (class1 class2) + (not (null (member (car (sb-pcl:class-precedence-list class2)) + (sb-pcl:class-precedence-list class1) + ) ) ) ) + #+(or CLISP ALLEGRO cmu sbcl) SUBCLASSP) + +(my-assert + (subclassp (find-class 'number) + (find-class 't)) + T) + +(my-assert + (subclassp (find-class 'integer) + (find-class 'number)) + T) + +(my-assert + (subclassp (find-class 'float) + (find-class 'number)) + T) diff --git a/src/ansi-tests/cmucl-bugs.lisp b/src/ansi-tests/cmucl-bugs.lisp new file mode 100644 index 000000000..a0546d13e --- /dev/null +++ b/src/ansi-tests/cmucl-bugs.lisp @@ -0,0 +1,640 @@ +;;; -*- mode: lisp -*- +(in-package :cl-user) + +;; Your fd-stream-read-n-bytes (in 17e) crashes when reading from a +;; pipe and it didn't get the requested byte-count (it should re-read +;; because pipe-reads may be interrupted). You have done some changes +;; in from 17c to 17e (I think) but it dosen't work yet. Here is a old +;; patched version that works for us. + + +;;An alist with SETF and a function name causes +;;an error whenever it's used: + +(my-assert + (defparameter foo '((setf . sqrt))) + FOO) + + +(my-assert + foo + ((SETF . SQRT))) + + +(my-assert + (setq foo '((zut . 4))) + ((ZUT . 4))) + + +(my-assert + foo + ((ZUT . 4))) + + +(my-assert + (setq foo '((setf . 3))) + ((SETF . 3))) + + +(my-assert + '(setq . 2) + (setq . 2)) + +(unintern 'foo) + +;; + + +(my-assert + (* 10000000000000000000000000000000000000000 + 10000000000000000000000000000000000000000) + + 100000000000000000000000000000000000000000000000000000000000000000000000000000000) + + +(my-assert + (time (+ 2 2)) + 4) + +;; cltl2 p 727 + + +(my-assert + (let ((stack (copy-list '(a b c d e f)))) + (loop for item = (length stack) then (pop stack) while stack + collect item)) + (6 A B C D E)) + +;; p 737 + +(my-assert + (loop with ( a b c) (float integer float) + return (list a b c)) + (0.0 0 0.0)) + + +(my-assert + (loop with ( a b c) float + return (list a b c)) + (0.0 0.0 0.0)) + + +;; printing arrays + + +(my-assert + (make-array '(22) :element-type 'single-float :initial-element 0.0) + #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)) + + +(my-assert + (make-array '(2 2)) + #-clisp + #2A((0 0) (0 0)) + #+clisp + #2A((NIL NIL) (NIL NIL))) + + +(my-assert + (make-array '(2 2) :element-type 'single-float :initial-element 0.0) + #2A((0.0 0.0) (0.0 0.0))) + +;; without pretty-print? + +(my-assert + (make-array '(22) :element-type 'single-float :initial-element 0.0) + #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)) + + +(my-assert + (make-array '(2 2)) + #-clisp + #2A((0 0) (0 0)) + #+clisp + #2A((NIL NIL) (NIL NIL))) + +(my-assert + (make-array '(2 2) :element-type 'single-float :initial-element 0.0) + #2A((0.0 0.0) (0.0 0.0))) + +;; bignums + + +(my-assert + (defun factorial (n &optional (i 1)) + (if (plusp n) (factorial (1- n) (* i n)) i)) + FACTORIAL) + + +(my-assert + (/ (factorial 100) (factorial 99)) + 100) + + +(my-assert + (/ (factorial 1000) (factorial 999)) + 1000) + +(unintern 'factorial) + +(my-assert + 1e-37 + 10.0e-38) + + +(my-assert + 1L-38 + 10.0L-39) + + +(my-assert + (flet ((print-result (x) + (format nil "~&x is ~F (a ~S)." x (type-of x)))) + (print-result "non-number")) + "x is non-number (a (SIMPLE-BASE-STRING 10))." + "Notice that ~3,2F does work.") + +(my-assert + (defun sigmoid (x) + (/ 1 (1+ (exp (- x))))) + SIGMOID) + + +(my-assert + (compile 'sigmoid) ; in CMU Common Lisp 17f + SIGMOID) + +#-clisp +(my-assert + (sigmoid 100) + 1.0) + + +(unintern 'sigmoid) + +(my-assert + (setq X (copy-list '((1 2) (1 2 3) (3)))) + ((1 2) (1 2 3) (3))) + + +(my-assert + (remove-duplicates X :test #'subsetp) + ((1 2 3) (3))) + + +(my-assert + (delete-duplicates X :test #'subsetp) + ((1 2 3) (3))) + + +(unintern 'X) + +(my-assert + (progn + (run-program "/bin/date" '() :output t :error :stream) + t) + t) +;; # + + + +(my-assert + (- 0.0 #C( 1.0 1.0)) + #C(-1.0 -1.0)) + + +(my-assert + (- #C(.5 .866) 0.0) + #C(0.5 0.866)) + + + +(my-assert + (/ 2.0 #C(-1.0 -1.0)) + #C(-1.0 1.0)) + + +(my-assert + (* 2.0 #C(-1.0 -1.0)) + #C(-2.0 -2.0)) + + + +(my-assert + (with-open-file + (foo "/tmp/foocl" + :direction :output + :element-type + (list 'signed-byte (1+ (integer-length + most-positive-fixnum)))) + (write-byte 17 foo) + (write-byte -17 foo) + (write-byte 4517 foo) + (write-byte -1217 foo)) + -1217) + + +(my-assert + (with-open-file + (foo "/tmp/foocl" + :direction :input + :element-type + (list 'signed-byte (1+ (integer-length + most-positive-fixnum)))) + (list (read-byte foo) + (read-byte foo) + (read-byte foo) + (read-byte foo))) + (17 -17 4517 -1217)) + + +(my-assert + (unless (ignore-errors (error "grr")) + (print "hi")) + "hi") + + +(my-assert + (setf (elt '(a b c d) 2) 'x) + x) + + +(my-assert + (acos 1.00001) + #+(or cmu sbcl) + #C(0.0 0.004475168) + #+clisp + #C(0 0.0044751023) + #-(or clisp cmu sbcl) + fill-this-in) + + +(my-assert + (parse-namestring (make-pathname :defaults "tst")) + #p"tst") + + +(my-assert + (string< "abcd" "012abcz" :start2 3 :end2 6) + NIL) + + +(my-assert + (string> "abcd" "012abcd" :start2 3 :end2 5) + 2) + + +(my-assert + (defun (setf foo) () t) + (setf foo)) + + +(my-assert + (compile '(setf foo)) + (setf foo)) + + +(my-assert + (typep '(setf cons) + 'generic-function) + NIL) + + +(my-assert + (make-sequence '(vector float) 4 :initial-element 0.0) + #(0.0 0.0 0.0 0.0)) + + +(my-assert + (typep (complex 0.0d0) '(complex double-float)) + t + "complex returns a number whose real part is realpart +and whose imaginary part is imagpart. + +If realpart is a rational and imagpart is the rational +number zero, the result of complex is realpart, a rational. +Otherwise, the result is a complex. + +If either realpart or imagpart is a float, the non-float +is converted to a float before the complex is created. If +imagpart is not supplied, the imaginary part is a zero of + the same type as realpart; i.e., (coerce 0 (type-of +realpart)) is effectively used. + +the second parameter is not supplied, the first is +a double-float, so actually this is (complex 0.0d0 0.0d0) +these are not rationals, so we get a complex number back. +") + + +;; From: Gary Bunting +(my-assert + (setf xx (expt 3 32)) + 1853020188851841) + +(my-assert + (* xx xx) + 3433683820292512484657849089281) + + +#| ; +(defun bugged (x) + (labels ((f (y &optional trouble) ; <<< or &key or &rest .. + (if y + (let ((a (pop y))) + (f a))))) + +;;;; (f x) <<< +;;;; Error in function COMMON-LISP::ASSERT-ERROR: +;;;; The assertion (EQ (C::LAMBDA-TAIL-SET C::CALLER) +;;;; (C::LAMBDA-TAIL-SET (C::LAMBDA-HOME C::CALLEE))) +;;;; failed. + +;;; However this works ok. + (f x nil))) +|# +(my-assert + (defun bugged (x) + (labels ((f (y &optional trouble) ; <<< or &key or &rest .. + (if y + (let ((a (pop y))) + (f a))))) + (f x))) + BUGGED) + +(my-assert + (bugged (list (list))) + NIL) + +(unintern 'bugged) + +(my-assert + (defun tst() + (with-open-file + (stream "does-not-exist" :if-does-not-exist nil) + (unless stream + 'abacab))) + TST) + +(my-assert + (tst) + abacab) + +(unintern 'tst) + +(my-assert + (defun f (a b) + (declare (type (single-float 0.0 0.5) a) + (type (single-float 0.0 0.2) b) + (optimize (debug 0) (safety 0) (speed 3))) + (expt a b)) + F) + +(my-assert + (progn + (compile 'f) + t) + t) + +;;; deltax^2 == deltat + +;;; from Paul Werkowski + +(my-assert + (progn + (compile-file "compile-bug5.lisp") + :ok) + :ok) + +(my-assert + (progn + (compile-file "compile-bug6.lisp") + :ok) + :ok) + +(my-assert + (progn + (defclass cl1 ()()) + (defclass cl2 (cl1 missing)()) + (defclass cl4 ()()) + + (defmethod foo ((c cl2)) + c) + ;; method specializing on class with fwd reference + ;; ok so far + + ;; then this dies + + (defmethod foo ((c cl4)) + c) ;; add a new method to gf #'foo + t) + T) + +(my-assert + (progn + (defmethod foo ((f function)) + f) + (defun zzz (x) + x) + (foo #'zzz) ;; this is supposed to work. + t) + t) + +(unintern 'zzz) + +#+(or sbcl cmu) +(my-assert + (progn + (compile-file "compile-bug1.lisp") + :ok) + :ok) + + + +;;; From: William Harold Newman + +(my-assert + (equalp #\a 'a) + nil) + +(defun my-sxhash (x) + (declare (type double-float x)) + (sxhash x)) + +(my-assert + (eq (my-sxhash 1.2d0) + (sxhash 1.2d0)) + T) + +(my-assert + (progn + (compile 'my-sxhash) + (eq (my-sxhash 1.2d0) + (sxhash 1.2d0))) + T) + + +;;; From: Raymond Toy + +(defun tst2 (x n) + (declare (type (integer -134217728 134217728) x) + (type (integer -4 4) n) + (optimize (speed 3) (safety 0))) + (ash x n)) + +(my-assert + (compile 'tst2) + tst2) + +;; From pvaneynd: + +(my-assert + (exp 1) + 2.7182817) + +(my-assert + (macrolet ((foobar (a b) + `(+ ,a ,b))) + (foobar 2 4)) + 6) + +(my-assert + (macrolet ((foobar (a b) + `(+ ,a ,b))) + (foobar 2 4 5 6)) + program-error) + + +;;; From: Marco Antoniotti + +(my-assert + (progn + (defclass ccc () ()) + (setf (find-class 'ccc1) (find-class 'ccc)) + :ok) + :ok) + +(my-assert + (progn + (defmethod zut ((c ccc1)) 123) + :ok) + :ok) + + +;;; From: Fred Gilham + + +(my-assert + (progn + (compile-file "compile-bug2.lisp") + :ok) + :ok) + +;;; From: lyle@cogni.iaf.cnrs-gif.fr (Lyle Borg-Graham) + +(defun foo () + (loop for x from 1.0 to 10.0 + maximize x into max single-float)) + +(my-assert + (compile 'foo) + foo) + +;;; From: Timothy Miller + +#+(or cmu sbcl) +(my-assert + (> 2 single-float-positive-infinity) + NIL) + +;;; From: "Fernando D. Mato Mira" + +(defun prolog-length (p) + (let ((x (length (car p)))) + (reduce #'(lambda (v1 v2) + (declare (ignore v1)) + (setq x (+ x (length v2)))) + p))) + +(my-assert + (compile 'prolog-length) + prolog-length) + +(my-assert + (prolog-length (list (list 1 2) + (list 3))) + 3) + +(my-assert + (progn + (compile-file "compile-bug3.lisp") + :ok) + :ok) + +(my-assert + (progn + (compile-file "compile-bug4.lisp") + :ok) + :ok) + +(my-assert + (progn + (compile-file "compile-bug4nt.lisp") + :ok) + :ok) + +(my-assert + (prolog-length (list (list 1 2) + (list 3))) + 3) + +;;; From: Sam Steingold +#+UNIX +(my-assert + (let ((z (make-concatenated-stream + (make-string-input-stream "abc") + (open "/etc/hosts")))) + (read-line z) + (concatenated-stream-streams z) + :ok) + :ok) + + +;;; From: Hannu Koivisto + +(my-assert + (case t) + nil) + +;;; From: Raymond Toy + +(my-assert + (progn + (with-open-file (file "/tmp/foobar" + :direction :output + :if-exists :supersede) + (princ #\F file)) + (with-open-file (file "/tmp/foobar" + :direction :input) + (let ((c (peek-char nil file nil 'eof t))) + (list c (read file) + (peek-char nil file nil 'eof t))))) + (#\F F EOF)) + +;;; From Barry Margolin: + +#+cmu +(my-assert + (> (length + (pcl:generic-function-lambda-list + (ensure-generic-function 'change-class))) + 2) + T + "change-class (instance t) (new-class symbol) &rest initargs") + +;;; From the clisp CHANGES file: + + + + + diff --git a/src/ansi-tests/compile-bug1.lisp b/src/ansi-tests/compile-bug1.lisp new file mode 100644 index 000000000..913bff00e --- /dev/null +++ b/src/ansi-tests/compile-bug1.lisp @@ -0,0 +1,32 @@ +(in-package :cl-user) + +;; from Douglas Thomas Crosher + +;;; Compiling this file caused a type error in +;;; maybe-convert-to-assignment due to a continuation-dest being +;;; null. One of the refs to the inlined definition of nthcdr had been +;;; marked for deletion, but this was seen. The path is ir1-optimize, +;;; flush-dead-code; delete-ref; then maybe-convert-to-assignment. +;;; +;;; After patching maybe-convert-to-assignment to abort in this case, +;;; the code compiles but compiles to a type error. Seems to be a +;;; problem propagating the argument type to the inlined nthcdr +;;; function? +;;; + +(declaim (optimize (space 0) (debug 2) + (c::compilation-speed 0) (speed 0) + (c::brevity 0) (safety 0))) + +(proclaim '(inline wrappers (setf wrappers))) +(defun wrappers (structure) + (declare (type list structure)) + (elt structure 2)) +(defun (setf wrappers) (new-value structure) + (declare (type list structure)) + (setf (elt structure 2) new-value)) + +(defun tst (x) + (let ((wrappers (prog1 (wrappers x) (setf (wrappers x) nil))) + (fns (nthcdr 0 x))) + (car (nthcdr 0 x)))) diff --git a/src/ansi-tests/compile-bug2.lisp b/src/ansi-tests/compile-bug2.lisp new file mode 100644 index 000000000..7f8be338d --- /dev/null +++ b/src/ansi-tests/compile-bug2.lisp @@ -0,0 +1,33 @@ +(in-package :cl-user) +;;; From: Fred Gilham + +(let* ((original-read-table *readtable*) + (snepslog-read-table (copy-readtable nil)) + (*readtable* snepslog-read-table)) + (set-macro-character + #\, + #'(lambda (s c) (declare (ignore s c)) (quote \,))) + (set-macro-character + #\~ + #'(lambda (s c) (declare (ignore s c)) (quote \~))) + (set-macro-character + #\. + #'(lambda (s c) (declare (ignore s c)) (quote \.))) + (set-macro-character + #\: + #'(lambda (s c) (declare (ignore s c)) (quote \:))) + (set-macro-character + #\{ + #'(lambda (s c) (declare (ignore s c)) (quote \{))) + (set-macro-character + #\} + #'(lambda (s c) (declare (ignore s c)) (quote \}))) + + (defun snepslogreadon () + "Sets the readtable to the snepslog read table" + (setq *readtable* snepslog-read-table)) + + (defun snepslogreadoff () + "Sets the readtable to the original readtable +(a copy of the initial readtable)" + (setq *readtable* original-read-table))) diff --git a/src/ansi-tests/compile-bug3.lisp b/src/ansi-tests/compile-bug3.lisp new file mode 100644 index 000000000..45c3b039a --- /dev/null +++ b/src/ansi-tests/compile-bug3.lisp @@ -0,0 +1,11 @@ +(in-package :cl-user) + +;;; From: "Fernando D. Mato Mira" + +(defun prolog-length (p) + (let ((x (length (car p)))) + (reduce #'(lambda (v1 v2) + (declare (ignore v1)) + (setq x (+ x (length v2)))) + p))) + diff --git a/src/ansi-tests/compile-bug4.lisp b/src/ansi-tests/compile-bug4.lisp new file mode 100644 index 000000000..559d59a2f --- /dev/null +++ b/src/ansi-tests/compile-bug4.lisp @@ -0,0 +1,36 @@ +(in-package "CL-USER") + +(defun equal-terms (termx termy) + (labels + ((alpha-equal-bound-term-lists (listx listy) + (or (and (null listx) (null listy)) + (and listx listy + (let ((bindings-x (bindings-of-bound-term (car listx))) + (bindings-y (bindings-of-bound-term (car listy)))) + (if (and (null bindings-x) (null bindings-y)) + (alpha-equal-terms (term-of-bound-term (car listx)) + (term-of-bound-term (car listy))) + (and (= (length bindings-x) (length bindings-y)) + (prog2 + (enter-binding-pairs (bindings-of-bound-term (car listx)) + (bindings-of-bound-term (car listy))) + (alpha-equal-terms (term-of-bound-term (car listx)) + (alpha-equal-terms (term-of-bound-term (car listx)) + (term-of-bound-term (car listy))) + (exit-binding-pairs (bindings-of-bound-term (car listx)) + (bindings-of-bound-term (car listy))))))) + (alpha-equal-bound-term-lists (cdr listx) (cdr listy))))) + + (alpha-equal-terms (termx termy) + (if (and (variable-p termx) + (variable-p termy)) + (equal-bindings (id-of-variable-term termx) + (id-of-variable-term termy)) + (and (equal-operators-p (operator-of-term termx) (operator-of-term termy)) + (alpha-equal-bound-term-lists (bound-terms-of-term termx) + (bound-terms-of-term termy)))))) + + (or (eq termx termy) + (and termx termy + (with-variable-invocation (alpha-equal-terms termx termy))))))) + diff --git a/src/ansi-tests/compile-bug4nt.lisp b/src/ansi-tests/compile-bug4nt.lisp new file mode 100644 index 000000000..9a86d18ec --- /dev/null +++ b/src/ansi-tests/compile-bug4nt.lisp @@ -0,0 +1,34 @@ +(in-package "USER") + +(defun equal-terms (termx termy) + (labels + ((alpha-equal-bound-term-lists (listx listy) + (or (and (null listx) (null listy)) + (and listx listy + (let ((bindings-x (bindings-of-bound-term (car listx))) + (bindings-y (bindings-of-bound-term (car listy)))) + (if (and (null bindings-x) (null bindings-y)) + (alpha-equal-terms (term-of-bound-term (car listx)) + (term-of-bound-term (car listy))) + (and (= (length bindings-x) (length bindings-y)) + (prog2 + (enter-binding-pairs (bindings-of-bound-term (car listx)) + (bindings-of-bound-term (car listy))) + (alpha-equal-terms (term-of-bound-term (car listx)) + (term-of-bound-term (car listy))) + (exit-binding-pairs (bindings-of-bound-term (car listx)) + (bindings-of-bound-term (car listy))))))) + (alpha-equal-bound-term-lists (cdr listx) (cdr listy))))) + + (alpha-equal-terms (termx termy) + (if (and (variable-p termx) + (variable-p termy)) + (equal-bindings (id-of-variable-term termx) + (id-of-variable-term termy)) + (and (equal-operators-p (operator-of-term termx) (operator-of-term termy)) + (alpha-equal-bound-term-lists (bound-terms-of-term termx) + (bound-terms-of-term termy)))))) + + (or (eq termx termy) + (and termx termy + (with-variable-invocation (alpha-equal-terms termx termy)))))) diff --git a/src/ansi-tests/compile-bug5.lisp b/src/ansi-tests/compile-bug5.lisp new file mode 100644 index 000000000..e0409066e --- /dev/null +++ b/src/ansi-tests/compile-bug5.lisp @@ -0,0 +1,20 @@ +(in-package :cl-user) + +(defun tickle-bug () + (labels ((fun1 () + (fun2)) + (fun2 () + (when nil + (tagbody + tag + (fun2) + (go tag))) + (when nil + (tagbody + tag + (fun1) + (go tag))))) + + (fun1) + nil)) + diff --git a/src/ansi-tests/compile-bug6.lisp b/src/ansi-tests/compile-bug6.lisp new file mode 100644 index 000000000..a3d4506f5 --- /dev/null +++ b/src/ansi-tests/compile-bug6.lisp @@ -0,0 +1,9 @@ +(in-package :cl-user) + +(defclass super1 () ()) + +(defclass sub1 (super1)()) + +(defun fooey () + (make-instance 'sub1)) + diff --git a/src/ansi-tests/conditions.lisp b/src/ansi-tests/conditions.lisp new file mode 100644 index 000000000..3f9f6f085 --- /dev/null +++ b/src/ansi-tests/conditions.lisp @@ -0,0 +1,554 @@ +;;; based on v1.6 -*- mode: lisp -*- +;;;; Test suite for the Common Lisp condition system +;;;; Written by David Gadbois 30.11.1993 +(in-package :cl-user) + +;;; +;;; Helpers +;;; + +#+(or clisp allegro cmu sbcl) +(my-assert + #+CLISP + (defun my-cpl (class) + (clos::class-precedence-list (clos:find-class class)) + ) + #+ALLEGRO + (defun my-cpl (class) + (clos:finalize-inheritance (find-class class)) + (clos:class-precedence-list (find-class class)) + ) + #+cmu + (defun my-cpl (class) + (pcl:class-precedence-list (find-class class)) + ) + #+sbcl + (defun my-cpl (class) + (sb-pcl:class-precedence-list (find-class class)) + ) + MY-CPL) + +(my-assert + (defun check-superclasses (class expected) + (let ((expected (list* class 't + #+CLISP 'clos:standard-object + #+ALLEGRO 'standard-object + #+(or cmu sbcl) 'instance + 'condition expected)) + (super (mapcar #' #+CLISP clos:class-name + #+ALLEGRO class-name + #+cmu pcl:class-name + #+sbcl sb-pcl:class-name + (my-cpl class)))) + (and (null (set-difference super expected)) + (null (set-difference expected super))))) + CHECK-SUPERCLASSES) + +;;; +;;; IGNORE-ERRORS +;;; +;;; If this does not work, none of the tests that check for getting an error +;;; will. + +;;; IGNORE-ERRORS should work. +(my-assert + (multiple-value-bind (value condition) + (ignore-errors (error "Foo")) + (list value (type-of condition))) + (nil simple-error)) + +;;; IGNORE-ERRORS should not interfere with values in non-error situations. +(my-assert + (multiple-value-list + (ignore-errors (values 23 42))) + (23 42)) + +;;; +;;; Predefined condition types. +;;; + +(my-assert + (check-superclasses 'warning '()) T) + + +(my-assert + (check-superclasses 'style-warning '(warning)) + T) + +(my-assert + (check-superclasses 'serious-condition '()) + T) + +(my-assert + (check-superclasses 'error '(serious-condition)) + T) + +(my-assert + (check-superclasses 'cell-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'parse-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'storage-condition '(serious-condition)) + T) + +(my-assert + (check-superclasses 'simple-error '(simple-condition error serious-condition)) + T) + +(my-assert + (check-superclasses 'simple-condition '()) + T) + +(my-assert + (check-superclasses 'simple-warning '(simple-condition warning)) + T) + +(my-assert + (check-superclasses 'file-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'control-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'program-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'undefined-function '(cell-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'arithmetic-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'division-by-zero '(arithmetic-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'floating-point-invalid-operation '(arithmetic-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'floating-point-inexact '(arithmetic-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'floating-point-overflow '(arithmetic-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'floating-point-underflow '(arithmetic-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'unbound-slot '(cell-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'package-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'print-not-readable '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'reader-error '(parse-error stream-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'stream-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'end-of-file '(stream-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'unbound-variable '(cell-error error serious-condition)) + T) + +(my-assert + (check-superclasses 'type-error '(error serious-condition)) + T) + +(my-assert + (check-superclasses 'simple-type-error + '(simple-condition + type-error error serious-condition)) + T + "Condition Type SIMPLE-TYPE-ERROR + +Class Precedence List: + +simple-type-error, simple-condition, type-error, error, serious-condition, condition, t +") + +;;; +;;; Defining conditions. +;;; +(my-assert + (progn (define-condition test () ()) t) + T) + +(my-assert + (check-superclasses 'test '()) + T) + +(my-assert + (progn (define-condition test2 (test) ()) t) + T) + +(my-assert + (check-superclasses 'test2 '(test)) + T) + +(my-assert + (progn (define-condition test3 (test2 simple-condition) ()) t) + T) + +(my-assert + (check-superclasses 'test3 '(test2 test simple-condition)) + T) + +;;; +;;; Making conditions +;;; +(my-assert + (progn (make-condition 'test) t) + T) + +(my-assert + (ignore-errors (progn (make-condition 'integer) t)) + NIL) + +;;; +;;; :REPORT option to DEFINE-CONDITION +;;; +(my-assert + (progn (define-condition test4 (test3) + () + (:report (lambda (condition stream) + (format stream "Yow! -- ~S" (type-of condition))))) + t) + T) + +(my-assert + (with-output-to-string (s) (princ (make-condition 'test4) s)) + "Yow! -- TEST4") + +(my-assert + (progn (define-condition test5 (test4) ()) t) + T) + +(my-assert + (with-output-to-string (s) (princ (make-condition 'test5) s)) + "Yow! -- TEST5") + +(my-assert + (with-output-to-string (s) + (princ (make-condition 'test3 + :format-control "And How! -- ~S" + :format-arguments '(23)) s)) + "And How! -- 23" + "From simple-condition: + +The type simple-condition represents conditions that are signaled by +signal whenever a format-control is supplied as the function's first +argument. The format control and format arguments are initialized with +the initialization arguments named :format-control and +:format-arguments to make-condition, and are accessed by the functions +simple-condition-format-control and +simple-condition-format-arguments. If format arguments are not +supplied to make-condition, nil is used as a default. " + ) + +;;; +;;; Condition slots. +;;; +(my-assert + (progn (define-condition test6 (test4) + ((foo :initarg :foo :initform 23 :accessor test6-foo)) + (:report (lambda (condition stream) + (format stream "~S -- ~S" + (type-of condition) + (test6-foo condition))))) + t) + T) + +(my-assert + (test6-foo (make-condition 'test6)) + 23) + +(my-assert + (test6-foo (make-condition 'test6 :foo 42)) + 42) + +(my-assert + (setf (test6-foo (make-condition 'test6 :foo 42)) 17) + 17) + +(my-assert + (with-output-to-string (s) (princ (make-condition 'test6 :foo 42) s)) + "TEST6 -- 42") + +;;; +;;; HANDLER-BIND +;;; + +;;; You do not have to bind handlers. +(my-assert + (ignore-errors + (handler-bind + () + (error "Foo"))) + nil) + +;;; Handlers should not interfere with values in non-error situations. +(my-assert + (multiple-value-list + (block foo + (handler-bind + ((error #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (values 42 17)))) + (42 17)) + +;;; Handlers should work. +(my-assert + (multiple-value-list + (block foo + (handler-bind + ((error #'(lambda (c) + (declare (ignore c)) + (return-from foo (values 23 17))))) + (error "Foo")))) + (23 17)) + +;;; Only the appropriate handlers should be called. +(my-assert + (ignore-errors + (block foo + (handler-bind + ((type-error #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (error "Foo")))) + nil) + +;;; Handlers can be specified type expressions. +(my-assert + (block foo + (handler-bind + (((or type-error error) + #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (error "Foo"))) + 23 + "typespecifier can be non-trivial.") + +;;; Handlers should be undone. +(my-assert + (ignore-errors + (block foo + (let ((first-time t)) + (handler-bind + ((error + #'(lambda (c) + (declare (ignore c)) + (if first-time + (progn + (setq first-time nil) + (error "Bar")) + (return-from foo 23))))) + (error "Foo"))))) + nil) + +;;; Handlers should be undone. +(my-assert + (block foo + (let ((first-time t)) + (handler-bind + ((error + #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (handler-bind + ((error + #'(lambda (c) + (declare (ignore c)) + (if first-time + (progn + (setq first-time nil) + (error "Bar")) + (return-from foo 42))))) + (error "Foo"))))) + 23) + +;;; Handlers in the same cluster should be accessible. +(my-assert + (ignore-errors + (block foo + (handler-bind + ((error + #'(lambda (c) (declare (ignore c)) nil)) + (error + #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (error "Foo")))) + 23 + "If a handler declines (ie. just return) the next available is used, so + the first one just returns nil, and the second, returning 23 is called") + +;;; Multiple handlers should work. +(my-assert + (block foo + (handler-bind + ((type-error + #'(lambda (c) + (declare (ignore c)) + (return-from foo 42))) + (error + #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (error "Foo"))) + 23) + +;;; Handlers should be undone. +(my-assert + (block foo + (handler-bind + ((error #'(lambda (c) + (declare (ignore c)) + (return-from foo 23)))) + (block bar + (handler-bind + ((error #'(lambda (c) + (declare (ignore c)) + (return-from foo 42)))) + (return-from bar))) + (error "Foo"))) + 23) + +;;; +;;; HANDLER-CASE +;;; + +;;; HANDLER-CASE should handle errors. +(my-assert + (multiple-value-list + (handler-case + (error "Foo") + (error (c) (when (typep c 'error) (values 23 42))))) + (23 42)) + +;;; Except those it doesn't handle. +(my-assert + (ignore-errors + (handler-case + (error "Foo") + (type-error () 23))) + NIL) + +;;; You don't have to specify handlers. +(my-assert + (ignore-errors + (handler-case + (error "Foo"))) + NIL) + +;;; HANDLER-CASE should not interfere with values in non-error situations. +(my-assert + (multiple-value-list + (handler-case + (values 42 17) + (error () 23))) + (42 17)) + +;;; :NO-ERROR should return values. +(my-assert + (multiple-value-list + (handler-case + (values 23 42) + (:no-error (a b) + (values b a)))) + (42 23)) + +;;; Except when there is an error. +(my-assert + (handler-case + (error "Foo") + (error () 23) + (:no-error (&rest args) (declare (ignore args)) 42)) + 23) + +;;; Or if it is not the last clause. +(my-assert + (handler-case + 23 + (:no-error (v) (1+ v)) + (error () 42)) + 24 + "The spec is not 100% clear here... +Macro HANDLER-CASE + +Syntax: + +handler-case expression [[{error-clause}* | no-error-clause]] => result* + +clause::= error-clause | no-error-clause + +So in the cause thing the no-error-clause can be everwhere, +in the real thing it looks like it can only be last. + +Need to ask comp.lang.lisp... + +") + +;;; Multiple handlers should be OK. +(my-assert + (handler-case + (error "Foo") + (type-error () 23) + (error () 42)) + 42) + +;;; Handlers should get undone. +(my-assert + (ignore-errors + (progn + (block foo + (handler-case + (return-from foo 23) + (error () 42))) + (error "Foo"))) + NIL) + +;;; Ditto. +(my-assert + (ignore-errors + (block foo + (let ((first-time t)) + (handler-case + (error "Foo") + (error () + (if first-time + (progn + (setf first-time nil) + (error "Bar")) + (return-from foo 23))))))) + NIL) + + + diff --git a/src/ansi-tests/eval20.lisp b/src/ansi-tests/eval20.lisp new file mode 100644 index 000000000..b0e2959ee --- /dev/null +++ b/src/ansi-tests/eval20.lisp @@ -0,0 +1,68 @@ +;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +;; testen abschitt 20 + + +;; eval + +(my-assert + (eval (list 'cdr + '(car (list (cons 'a 'b) 'c)))) + b) + +(my-assert + (makunbound 'x) + x) + +(my-assert + (eval 'x) + UNBOUND-VARIABLE) + +(my-assert + (setf x 3) + 3) + +(my-assert + (eval 'x) + 3) + +;; constantp + +(my-assert + (constantp 2) + T) + +(my-assert + (constantp #\r) + T) + +(my-assert + (constantp "max") + T) + +(my-assert + (constantp '#(110)) + T) + +(my-assert + (constantp :max) + T) + +(my-assert + (constantp T) + T) + +(my-assert + (constantp NIL) + T) + +(my-assert + (constantp 'PI) + #-CLISP T + #+CLISP NIL) + +(my-assert + (constantp '(quote foo)) + T) + diff --git a/src/ansi-tests/excepsit.lisp b/src/ansi-tests/excepsit.lisp new file mode 100644 index 000000000..e72674dea --- /dev/null +++ b/src/ansi-tests/excepsit.lisp @@ -0,0 +1,1574 @@ +;;; based on 1.6 -*- mode: lisp -*- +(in-package :cl-user) + +;;; Test "Exceptional situations" as specified by CLHS + +;; NB: CLHS section 1.4.2 implies that we have to verify only those +;; specifications which have the wording "an error is signalled" or +;; "an error should be signalled". + +#-(or cmu sbcl);; XXXX +(my-assert + (abort) + control-error) + +(my-assert + (acos 'x) + type-error) + +(my-assert + (acosh 'x) + type-error) + +(my-assert + (progn + (defgeneric foo01 (x)) + (defmethod foo01 ((x number)) t) + (let ((m (find-method #'foo01 nil (list (find-class 'number))))) + (remove-method #'foo01 m) + (defgeneric foo01 (x y)) + (add-method #'foo01 m) + ) ) + error) + +#-CLISP +(my-assert + ;; documented behaviour of ADD-METHOD + (progn + (defgeneric foo02 (x)) + (defmethod foo02 ((x number)) t) + (let ((m (find-method #'foo02 nil (list (find-class 'number))))) + ; wrong, not? (remove-method #'foo02 m) + (defgeneric foo03 (x)) + (add-method #'foo03 m) + ) ) + error + "add-method:... + +If method is a method object of another generic function, +an error of type error is signaled. ") + +(my-assert + (let ((a (make-array 5 :adjustable t))) + (adjust-array a 4 :fill-pointer 1) + ) + error) + +(my-assert + (adjustable-array-p '(x)) + type-error) + +(my-assert + (alpha-char-p 33) + type-error) + +(my-assert + (alphanumericp 33) + type-error) + +(my-assert + (array-dimensions '(x)) + type-error) + +(my-assert + (array-displacement '(x)) + type-error) + +(my-assert + (array-element-type '(x)) + type-error) + +(my-assert + (array-has-fill-pointer-p '(x)) + type-error) + +(my-assert + (array-rank '(x)) + type-error) + +(my-assert + (array-total-size '(x)) + type-error) + +(my-assert + (ash 3/4 2) + type-error) + +(my-assert + (ash 3 4.0) + type-error) + +(my-assert + (asin 'x) + type-error) + +(my-assert + (asinh 'x) + type-error) + +(my-assert + (atan 'x) + type-error) + +(my-assert + (atan #c(0 0.4) 3.4) + type-error) + +(my-assert + (atan -4 #c(3 4)) + type-error) + +(my-assert + (atanh 'x) + type-error) + +(my-assert + (boole 'x 3 4) + type-error) + +(my-assert + (boole boole-and 3/4 -7) + type-error) + +(my-assert + (boole boole-set 5 #c(-3 4)) + type-error) + +(my-assert + (both-case-p 33) + type-error) + +(my-assert + (boundp 47) + type-error) + +(my-assert + (butlast '(a b c) -1) + type-error) + +(my-assert + (butlast '#(a b c)) + type-error) + +(my-assert + (car 'x) + type-error) + +(my-assert + (cdr '#(a b c)) + type-error) + +(my-assert + (cdadar '((x y))) + type-error) + +(my-assert + (progn + (defgeneric foo04 (x)) + (defmethod foo04 ((x real)) 'ok) + (defmethod foo04 ((x integer)) (call-next-method (sqrt x))) + (foo04 -1)) + error + "(sqrt -1) is not a real...") + +(my-assert + (progn + (defgeneric foo041 (x)) + (defmethod foo041 ((x real)) 'ok) + (defmethod foo041 ((x integer)) (call-next-method (sqrt x))) + (foo041 2)) + error + "CLHS: When providing arguments to CALL-NEXT-METHOD, the following + rule must be satisfied or an error of type ERROR should be signaled: + the ordered set of applicable methods for a changed set of arguments + for CALL-NEXT-METHOD must be the same as the ordered set of applicable + methods for the original arguments to the generic function.") + +(my-assert + (ccase 'x) + type-error) + +(my-assert + (char-code 33) + type-error) + +(my-assert + (char-downcase 33) + type-error) + +(my-assert + (char-equal) + program-error) + +(my-assert + (char-greaterp) + program-error) + +(my-assert + (char-lessp) + program-error) + +(my-assert + (char-name 33) + type-error) + +(my-assert + (char-not-equal) + program-error) + +(my-assert + (char-not-greaterp) + program-error) + +(my-assert + (char-not-lessp) + program-error) + +(my-assert + (char-upcase 33) + type-error) + +(my-assert + (char/=) + program-error) + +(my-assert + (char<) + program-error) + +(my-assert + (char<=) + program-error) + +(my-assert + (char=) + program-error) + +(my-assert + (char>) + program-error) + +(my-assert + (char>=) + program-error) + +(my-assert + (character "abc") + type-error) + +(my-assert + (character "") + type-error) + +(my-assert + (character 33) + type-error) + +(my-assert + (clear-input '*terminal-io*) + type-error) + +(my-assert + (clear-output '*terminal-io*) + type-error) + +(my-assert + (coerce '(a b c) '(vector * 4)) + type-error) + +(my-assert + (coerce '#(a b c) '(vector * 4)) + type-error) + +(my-assert + (coerce '(a b c) '(vector * 2)) + type-error) + +(my-assert + (coerce '#(a b c) '(vector * 2)) + type-error) + +(my-assert + (coerce "foo" '(string 2)) + type-error) + +(my-assert + (coerce '#(#\a #\b #\c) '(string 2)) + type-error) + +(my-assert + (coerce '(0 1) '(simple-bit-vector 3)) + type-error) + +(my-assert + (coerce nil 'nil) + type-error) + +(my-assert + (coerce '#:nonexistent 'function) + error) + +(my-assert + (coerce 'and 'function) + error) + +(my-assert + (compile-file "/tmp/12836123.lsp") + file-error) + +(my-assert + (concatenate 'symbol) + error) + +(my-assert + (concatenate '(string 3) "ab" "cd") + type-error) + +#-CLISP +(my-assert + (copy-pprint-dispatch 'x) + type-error) + +(my-assert + (copy-seq 'x) + type-error) + +(my-assert + (copy-symbol #\x) + type-error) + +(my-assert + (cos 'x) + type-error) + +(my-assert + (cosh 'x) + type-error) + +(my-assert + (count #\x 'x) + type-error) + +(my-assert + (let ((x nil)) (ctypecase x)) + type-error) + +(my-assert + (decode-float 2/3) + type-error) + +(my-assert + (defclass foo05 () (a b a)) + program-error + "defclass: +... +If there are any duplicate slot names, +an error of type program-error is signaled. ") + +(my-assert + (defclass foo06 () (a b) (:default-initargs x a x b)) + program-error + "defclass: +... +If an initialization argument name appears more +than once in :default-initargs class option, an +error of typeprogram-error is signaled. ") + +(my-assert + (defclass foo07 () ((a :allocation :class :allocation :class))) + program-error + "defclass: +... +If any of the following slot options appears more than once in a +single slot description, an error of type program-error is +signaled: :allocation, :initform, :type, :documentation.") + +(my-assert + (defclass foo08 () ((a :initform 42 :initform 42))) + program-error + "defclass: +... +If any of the following slot options appears more than once in a +single slot description, an error of type program-error is +signaled: :allocation, :initform, :type, :documentation.") + +(my-assert + (defclass foo09 () ((a :type real :type real))) + program-error + "defclass: +... +If any of the following slot options appears more than once in a +single slot description, an error of type program-error is +signaled: :allocation, :initform, :type, :documentation.") + +(my-assert + (defclass foo10 () ((a :documentation "bla" :documentation "blabla"))) + program-error + "defclass: +... +If any of the following slot options appears more than once in a +single slot description, an error of type program-error is +signaled: :allocation, :initform, :type, :documentation.") + +(my-assert + (defgeneric if (x)) + program-error + "defgeneric: +... +If function-name names an ordinary function, +a macro, or a special operator, an error of type +program-error is signaled.") + +(my-assert + (progn + (defmacro foo11 (x) x) + (defgeneric foo11 (x))) + program-error + "defgeneric: +... +If function-name names an ordinary function, +a macro, or a special operator, an error of type +program-error is signaled.") + +(my-assert + (progn + (defun foo12 (x) x) + (defgeneric foo12 (x))) + program-error + "defgeneric: +... +If function-name names an ordinary function, +a macro, or a special operator, an error of type +program-error is signaled.") + +(my-assert + (defgeneric foo13 (x y &rest l) + (:method (x y)) + ) + error + "") + +(my-assert + (defgeneric foo14 (x) + (:documentation "bla") + (:documentation "blabla") + ) + program-error) + +(my-assert + (defgeneric foo15 (x) + (:my-option t)) + program-error) + +;; define-method-combination is too complicated + +(my-assert + (progn + (defvar foo16) + (define-symbol-macro foo16 t)) + program-error) + +(my-assert + (defmethod if (x) nil) + error) + +(my-assert + (progn + (defmacro foo17 (x) x) + (defmethod foo17 (x) nil)) + error) + +(my-assert + (progn + (defun foo18 (x) x) + (defmethod foo18 (x) nil)) + error) + +(my-assert + (progn + (defgeneric foo19 (x)) + (defmethod foo19 (x y) nil)) + error) + +(my-assert + (progn + (defpackage "FOO20") + (defpackage "FOO21" (:nicknames "FOO20"))) + package-error) + +(my-assert + (defpackage "FOO22" (:size 20) (:size 20)) + program-error) + +(my-assert + (defpackage "FOO23" (:documentation "bla") (:documentation "blabla")) + program-error) + +(my-assert + (defpackage "FOO24" (:my-option t)) + program-error) + +(my-assert + (defpackage "FOO25" (:shadow "IF") (:intern "IF")) + program-error) + +(my-assert + (defpackage "FOO26" (:shadow "IF") (:import-from "USER" "IF")) + program-error) + +(my-assert + (defpackage "FOO27" (:shadow "IF") (:shadowing-import-from "USER" "IF")) + program-error) + +(my-assert + (defpackage "FOO28" (:intern "IF") (:import-from "USER" "IF")) + program-error) + +(my-assert + (defpackage "FOO29" (:intern "IF") (:shadowing-import-from "USER" "IF")) + program-error) + +(my-assert + (defpackage "FOO30" (:import-from "USER" "IF") (:shadowing-import-from "USER" "IF")) + program-error) + +(my-assert + (defpackage "FOO31" (:export "IF") (:intern "IF")) + program-error) + +#-sbcl +(my-assert + (defstruct foo32 a system::a) + program-error) + +#-sbcl +(my-assert + (progn + (defstruct foo33 a) + (defstruct (foo34 (:include foo33)) system::a)) + program-error) + +(my-assert + (delete #\x 'x) + type-error) + +(my-assert + (delete-duplicates 'abba) + type-error) + +;; deleting a non-existing file can be successful! +;; the results are not easily predictable across implementations +;;(my-assert +;; (progn +;; (with-open-file (s "/tmp/foo35.tmp" :direction :output)) +;; (delete-file "/tmp/foo35.tmp/bar")) +;; nil or file-error??) + +(my-assert + (destructuring-bind (a) '(1 2) a) + error) + +;; directory - no way to make a directory search fail + +#-CLISP +(my-assert + ;; documented behaviour of DISASSEMBLE + (disassemble #x123456) + type-error) + +;; dribble - no way to force a file-error + +(my-assert + (ecase 'x) + type-error) + +(my-assert + (elt 'x 0) + type-error) + +(my-assert + (elt "abc" 4) + type-error) + +(my-assert + (elt '(a b c) 4) + type-error) + +(my-assert + (elt '#(a b c) 4) + type-error) + +(my-assert + (elt (make-array 3 :fill-pointer 3 :adjustable t) 4) + type-error) + +(my-assert + (endp 'x) + type-error) + +(my-assert + (ensure-directories-exist "/*/") + file-error) + +(my-assert + (error 42) + type-error) + +(my-assert + (let ((x nil)) (etypecase x)) + type-error) + +(my-assert + (every '(lambda (x) x) nil) + type-error) + +(my-assert + (every #'identity 'x) + type-error) + +(my-assert + (fboundp '(psetf aref)) + type-error) + +(my-assert + (fdefinition '(psetf aref)) + type-error) + +(my-assert + (fdefinition '#:nonexistent) + undefined-function) + +(my-assert + (file-author "*") + file-error) + +(my-assert + (file-length *terminal-io*) + type-error) + +(my-assert + (with-open-file (s "/tmp/foo35.tmp" :direction :output) + (file-position s 0.0)) + error) + +(my-assert + (with-open-file (s "/tmp/foo35.tmp" :direction :output) + (file-position s -1)) + error) + +(my-assert + (with-open-file (s "/tmp/foo35.tmp" :direction :input) + (file-position s (+ (file-length s) 1000))) + error) + +(my-assert + (not (delete-file "/tmp/foo35.tmp")) + nil) + +(my-assert + (file-write-date "*") + file-error) + +(my-assert + (fill 'x #\x) + type-error) + +(my-assert + (fill (make-list 3) 'x :start nil) + type-error) + +(my-assert + (fill (make-list 3) 'x :start -1) + type-error) + +(my-assert + (fill (make-list 3) 'x :start 1 :end -1) + type-error) + +(my-assert + (fill-pointer "abc") + type-error) + +(my-assert + (find #\x 'x) + type-error) + +(my-assert + (find-class '#:nonexistent t) + error) + +(my-assert + (progn + (defgeneric foo36 (x y)) + (find-method #'foo36 nil (list (find-class 'number)))) + error) + +(my-assert + (progn + (defgeneric foo37 (x)) + (find-method #'foo37 nil (list (find-class 'number)))) + error) + +(my-assert + (finish-output '*terminal-io*) + type-error) + +(my-assert + (float-digits 2/3) + type-error) + +(my-assert + (float-precision 2/3) + type-error) + +(my-assert + (float-radix 2/3) + type-error) + +(my-assert + (float-sign 2/3) + type-error) + +(my-assert + (float-sign -4.5 2/3) + type-error) + +(my-assert + (fmakunbound '(psetf aref)) + type-error) + +(my-assert + (force-output '*terminal-io*) + type-error) + +(my-assert + (funcall 'foo38) + undefined-function) + +(my-assert + (funcall 'and) + undefined-function) + +(my-assert + (gcd 4 3/4) + type-error) + +(my-assert + (gensym #\x) + type-error) + +(my-assert + (gentemp 't) + type-error) + +(my-assert + (gentemp "X" 24) + type-error) + +(my-assert + (get "a" 'x) + type-error) + +(my-assert + (get-dispatch-macro-character #\0 #\#) + error) + +(my-assert + (graphic-char-p 33) + type-error) + +(my-assert + (hash-table-rehash-size *readtable*) + type-error) + +(my-assert + (hash-table-rehash-threshold *package*) + type-error) + +(my-assert + (hash-table-size *random-state*) + type-error) + +(my-assert + (hash-table-test '#(a b c)) + type-error) + +(my-assert + (imagpart #\c) + type-error) + +(my-assert + #-CLISP + (in-package "FOO39") + #+CLISP + (common-lisp:in-package "FOO39") + package-error) + +(my-assert + (input-stream-p (pathname "abc")) + type-error) + +(my-assert + (integer-decode-float 2/3) + type-error) + +(my-assert + (integer-length 0.0) + type-error) + +(my-assert + (interactive-stream-p (pathname "abc")) + type-error) + +(my-assert + (invoke-restart 'foo40) + control-error) + +(my-assert + (invoke-restart-interactively 'foo41) + control-error) + +(my-assert + (isqrt -1) + type-error) + +(my-assert + (isqrt #c(3 4)) + type-error) + +(my-assert + (last '(a b c) -1) + type-error) + +(my-assert + (lcm 4/7 8) + type-error) + +(my-assert + (length 'x) + type-error) + +(my-assert + (list-length 'x) + type-error) + +(my-assert + (list-length '(x . y)) + type-error) + +(my-assert + (load "/tmp/128347234.lsp") + file-error) + +(my-assert + (load "*.lsp") + file-error) + +(my-assert + (load-logical-pathname-translations "FOO41") + error) + +(my-assert + (logand -3 2.3) + type-error) + +(my-assert + (logbitp -1 5) + type-error) + +(my-assert + (logbitp 2 3/7) + type-error) + +(my-assert + (logcount #*01010011) + type-error) + +(my-assert + (logical-pathname '#(#\A #\B)) + type-error) + +(my-assert + (logical-pathname-translations '#(#\A #\B)) + type-error) + +(my-assert + (lower-case-p 33) + type-error) + +(my-assert + (make-broadcast-stream (make-string-input-stream "abc")) + type-error) + +(my-assert + (make-concatenated-stream (make-string-output-stream)) + type-error) + +(my-assert + (progn + (defclass foo42 () ()) + (make-instance 'foo42 :x 1)) + error) + +(my-assert + (make-list -1) + type-error) + +(my-assert + (progn + (defstruct foo43) + (make-load-form (make-foo43))) + error) + +(my-assert + (make-random-state 'x) + type-error) + +(my-assert + (make-sequence 'x 5) + type-error) + +(my-assert + (make-sequence 'sequence 5) + type-error) + +(my-assert + (make-sequence '(string 3) 4) + type-error) + +(my-assert + (make-symbol 'x) + type-error) + +(my-assert + (make-synonym-stream *terminal-io*) + type-error) + +(my-assert + (make-two-way-stream (make-string-input-stream "abc") (make-string-input-stream "def")) + type-error) + +(my-assert + (make-two-way-stream (make-string-output-stream) (make-string-output-stream)) + type-error) + +(my-assert + (makunbound "xx") + type-error) + +(my-assert + (map 'x #'identity "abc") + type-error) + +(my-assert + (map '(string 3) #'identity "ab") + type-error) + +(my-assert + (max 3 #c(4 0.0)) + type-error) + +(my-assert + (merge '(vector * 5) '(3 1) '(2 4) #'<) + type-error) + +(my-assert + (min 3 #c(4 0.0)) + type-error) + +(my-assert + (minusp #c(4 -3/4)) + type-error) + +(my-assert + (muffle-warning) + control-error) + +(my-assert + (name-char '#(#\N #\u #\l)) + type-error) + +(my-assert + (nbutlast '(a b c) -1) + type-error) + +(my-assert + (nbutlast '#(a b c)) + type-error) + +(my-assert + (no-applicable-method #'cons) + error) + +(my-assert + (no-next-method #'print-object (find-method #'print-object nil (list (find-class 'standard-object) (find-class 't)))) + error) + +(my-assert + (notany '(lambda (x) x) nil) + type-error) + +(my-assert + (notany #'identity 'x) + type-error) + +(my-assert + (notevery '(lambda (x) x) nil) + type-error) + +(my-assert + (notevery #'identity 'x) + type-error) + +(my-assert + (nthcdr 2 '(a . b)) + type-error) + +(my-assert + (oddp 3.5) + type-error) + +#+UNIX +(my-assert + (progn (open "/etc/passwd" :direction :input :if-exists :error) (/ 0)) + division-by-zero) + +#+UNIX +(my-assert + (progn (open "/etc/nonexistent" :direction :input :if-exists :error) (/ 0)) + file-error) + +(my-assert + (open "/tmp/foo44nonexistent" :direction :input :if-does-not-exist :error) + file-error) + +(my-assert + (open "/tmp/*" :direction :input) + file-error) + +#+UNIX +(my-assert + (open "/etc/mtab" :direction :input :external-format 'mtab-entries) + error) + +(my-assert + (open-stream-p (pathname "foo45")) + type-error) + +(my-assert + (output-stream-p (pathname "foo46")) + type-error) + +(my-assert + (package-name 47) + type-error) + +(my-assert + (package-nicknames (pathname "foo47")) + type-error) + +(my-assert + (package-shadowing-symbols (vector 'a 'b 'c)) + type-error) + +(my-assert + (package-use-list (list 'a 'b 'c)) + type-error) + +(my-assert + (package-used-by-list (list 'a 'b 'c)) + type-error) + +(my-assert + (parse-integer "x-y") + error) + +(my-assert + (parse-namestring (coerce (list #\f #\o #\o (code-char 0) #\4 #\8) 'string)) + parse-error) + +(my-assert + (parse-namestring "foo48:a" (logical-pathname "foo49:")) + error) + +(my-assert + (pathname-match-p 34 "*") + type-error) + +(my-assert + (pathname-match-p "x" 34) + type-error) + +(my-assert + (peek-char nil (make-string-input-stream "") t) + end-of-file) + +(my-assert + (peek-char #\space (make-string-input-stream "") t) + end-of-file) + +#| ; It's not clear why peek-char should signal an error, where read-char and +;; read-line don't. Kent Pitman says: "Sounds like a mess." +(peek-char nil (make-string-input-stream "") nil nil t) +end-of-file +|# + +(my-assert + (phase 'x) + type-error) + +(my-assert + (plusp #c(0 4.2)) + type-error) + +#-CLISP +(my-assert + (pprint-dispatch nil t) + type-error) + +#-CLISP +(my-assert + (pprint-exit-if-list-exhausted) + error) + +#-CLISP +(my-assert + (pprint-indent nil 2) + error) + +#-CLISP +(my-assert + (let ((x (make-string-output-stream))) + (pprint-logical-block (x nil :prefix 24))) + type-error) + +#-CLISP +(my-assert + (let ((x (make-string-output-stream))) + (pprint-logical-block (x nil :prefix "a" :per-line-prefix "b"))) + error) + +#-CLISP +(my-assert + (pprint-newline :fresh) + type-error) + +#-CLISP +(my-assert + (pprint-pop) + error) + +(my-assert + (pprint-tab :paragraph 0 1) + error) + +(my-assert + (let ((*print-readably* t)) (print-unreadable-object (nil *standard-output*))) + print-not-readable) + +(my-assert + (probe-file "*") + file-error) + +(my-assert + (provide 25) + type-error) + +(my-assert + (random -2.3) + type-error) + +(my-assert + (rational #c(2.4 -0.3)) + type-error) + +(my-assert + (rationalize #c(2.4 -0.3)) + type-error) + +(my-assert + (read (make-string-input-stream "((a b)") nil) + end-of-file) + +(my-assert + (read (make-string-input-stream " ") t) + end-of-file) + +(my-assert + (read-byte (pathname "foo50")) + type-error) + +(my-assert + (read-byte (make-string-input-stream "abc")) + error) + +(my-assert + (let ((filename "/tmp/foo51.bin")) + (with-open-file (s filename :direction :output + :if-exists :overwrite + :if-does-not-exist :create)) + (with-open-file (s filename :direction :input + :element-type '(unsigned-byte 8)) + (read-byte s t))) + end-of-file) + +(my-assert + (not (delete-file "/tmp/foo51.bin")) + nil) + +(my-assert + (let ((filename "/tmp/foo52.txt")) + (with-open-file (s filename :direction :output + :if-exists :overwrite + :if-does-not-exist :create)) + (with-open-file (s filename :direction :input) + (read-char s t))) + end-of-file) + +(my-assert + (not (delete-file "/tmp/foo52.txt")) + nil) + +(my-assert + (let ((filename "/tmp/foo53.txt")) + (with-open-file (s filename :direction :output + :if-exists :overwrite + :if-does-not-exist :create)) + (with-open-file (s filename :direction :input) + (read-char-no-hang s t))) + end-of-file) + +(my-assert + (not (delete-file "/tmp/foo53.txt")) + nil) + +(my-assert + (read-from-string "((a b))" nil nil :end 6) + end-of-file) + +(my-assert + (read-from-string " () () " t nil :start 3 :end 4) + end-of-file) + +(my-assert + (read-line (make-string-input-stream "") t) + end-of-file) + +(my-assert + (read-sequence (list 1 2 3) (make-string-input-stream "") :start nil) + type-error) + +(my-assert + (read-sequence (list 1 2 3) (make-string-input-stream "") :end -1) + type-error) + +(my-assert + (readtable-case nil) + type-error) + +(my-assert + (setf (readtable-case *readtable*) ':unknown) + type-error) + +(my-assert + (realpart #\c) + type-error) + +(my-assert + (progn + (defclass foo54 () ()) + (reinitialize-instance (make-instance 'foo54) :dummy 0)) + error) + +(my-assert + (remove #\x 'x) + type-error) + +(my-assert + (remove-duplicates 'abba) + type-error) + +(my-assert + (remprop 55 'abc) + type-error) + +(my-assert + (rplaca nil 5) + type-error) + +(my-assert + (rplacd nil 5) + type-error) + +(my-assert + (scale-float 2/3 -1) + type-error) + +(my-assert + (scale-float 3.4 1.0) + type-error) + +(my-assert + (set-dispatch-macro-character #\0 #\# #'(lambda (s c n) (loop))) + error) + +(my-assert + (set-pprint-dispatch '(vector * 2) nil #c(3 4)) + error) + +(my-assert + (sin 'x) + type-error) + +(my-assert + (sinh 'x) + type-error) + +(my-assert + (sleep -1) + type-error) + +(my-assert + (progn + (defclass foo55 () (a)) + (slot-boundp (make-instance 'foo55) ':a)) + error) + +(my-assert + (progn + (defclass foo56 () (a)) + (slot-makunbound (make-instance 'foo56) ':a)) + error) + +(my-assert + (slot-missing (find-class 't) nil ':a 'setf) + error) + +(my-assert + (slot-unbound (find-class 't) nil ':a) + unbound-slot) + +(my-assert + (progn + (defclass foo57 () (a)) + (slot-value (make-instance 'foo57) ':a)) + error) + +(my-assert + (some '(lambda (x) x) nil) + type-error) + +(my-assert + (some #'identity 'x) + type-error) + +(my-assert + (special-operator-p '(and x y)) + type-error) + +(my-assert + (special-operator-p '(setf aref)) + type-error) + +(my-assert + (sqrt 'x) + type-error) + +(my-assert + (standard-char-p 33) + type-error) + +(my-assert + (stream-element-type '*terminal-io) + type-error) + +(my-assert + (string 33) + type-error) + +(my-assert + (symbol-function 33) + type-error) + +(my-assert + (symbol-function ':compile) + undefined-function) + +(my-assert + (symbol-macrolet ((t true))) + program-error) + +(my-assert + (symbol-macrolet ((*print-pretty* (stream-print-pretty *standard-output*)))) + program-error) + +(my-assert + (symbol-macrolet ((foo58 t)) (declare (special foo58))) + program-error) + +(my-assert + (symbol-name '(setf foo59)) + type-error) + +(my-assert + (symbol-package '(setf foo59)) + type-error) + +(my-assert + (symbol-plist '(setf foo59)) + type-error) + +(my-assert + (symbol-value '(setf foo59)) + type-error) + +(my-assert + (symbol-value '#:nonexistent) + unbound-variable) + +(my-assert + (tan 'x) + type-error) + +(my-assert + (tanh 'x) + type-error) + +(my-assert + (throw '#:nonexistent nil) + control-error) + +(my-assert + (translate-logical-pathname (make-broadcast-stream)) + type-error) + +(my-assert + (translate-logical-pathname (logical-pathname "foo61:")) + file-error) + +#-CLISP +(my-assert + ;; clisp explicitly allows symbols as pathnames + (translate-pathname 'x "x" "y") + type-error) + +#-CLISP +(my-assert + ;; clisp explicitly allows symbols as pathnames + (translate-pathname "a" '* '*) + type-error) + +(my-assert + (translate-pathname "x" "y" "z") + error) + +(my-assert + (truename "/tmp/foo62nonexistent") + file-error) + +(my-assert + (truename "/tmp/*/x") + file-error) + +(my-assert + (typep nil 'values) + error) + +(my-assert + (typep #'cons '(values t)) + error) + +(my-assert + (typep #'cons '(function (t t) list)) + error) + +(my-assert + (unexport ':foo63) + package-error) + +(my-assert + (progn + (defpackage "FOO64" (:export "XYZ")) + (defpackage "FOO65" (:export "XYZ")) + (defpackage "FOO66" (:use "FOO64" "FOO65") (:shadow "XYZ")) + (unintern (find-symbol "XYZ" (find-package "FOO66")) (find-package "FOO66"))) + error) + +;; update-instance-for-different-class too complicated + +;; update-instance-for-redefined-class too complicated + +(my-assert + (upper-case-p 33) + type-error) + +(my-assert + (values-list '(a b . c)) + type-error) + +(my-assert + (vector-pop "foo67") + type-error) + +(my-assert + (vector-pop (make-array 10 :fill-pointer 0)) + error) + +(my-assert + (vector-push 'x (make-array 10)) + error) + +(my-assert + (let ((a (make-array 5 + :fill-pointer 0 + :adjustable nil))) + (if (adjustable-array-p a) + 'error + (dotimes (i 100) (vector-push-extend 'x a)))) + error) + +(my-assert + (warn (make-condition 'error)) + type-error) + +(my-assert + (warn (make-condition 'warning) "x") + type-error) + +(my-assert + (warn 'error) + type-error) + +(my-assert + (wild-pathname-p #\x) + type-error) + +(my-assert + (write-byte 1 (pathname "foo67")) + type-error) + +(my-assert + (write-byte 1 (make-string-output-stream)) + error) + +(my-assert + (write-sequence '(#\1 #\2 #\3) (make-string-output-stream) :start nil) + type-error) + +(my-assert + (write-sequence '(#\1 #\2 #\3) (make-string-output-stream) :end -1) + type-error) + +(my-assert + (zerop 'x) + type-error) + +;; section 2.3.1.1 +(my-assert + (read-from-string "-35/000") + reader-error) ; not division-by-zero! + +(my-assert + (read-from-string "31e300") + reader-error) ; not floating-point-overflow! + diff --git a/src/ansi-tests/format.lisp b/src/ansi-tests/format.lisp new file mode 100644 index 000000000..41aa43cf1 --- /dev/null +++ b/src/ansi-tests/format.lisp @@ -0,0 +1,1295 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) + +;; **************************************************************************** +;; * Rosenmueller format.tst * +;; **************************************************************************** + +;; ~< ------------------------------------------------------------------------ +(my-assert + (format nil "~10") + "foo bar") + +(my-assert + (format nil "~10:") + " foo bar") + +(my-assert + (format nil "~10@") + "foo bar ") + +(my-assert + (format nil "~10:@") + #+(or XCL CLISP ALLEGRO) " foo bar " + #+(or AKCL cmu sbcl ecls) " foo bar " + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl ecls) UNKNOWN) + +(my-assert + (format nil "~10") + " foobar") + +(my-assert + (format nil "~10:") + " foobar") + +(my-assert + (format nil "~10@") + "foobar ") + +(my-assert + (format nil "~10:@") + " foobar ") + +;; ~< ~s ~^ --------------------------------------------------------------------- +(my-assert + (format nil "~15<~S~>" 'foo) + " foo") + +(my-assert + (format nil "~15<~S~;~^~S~>" 'foo) + " foo") + +(my-assert + (format nil "~15<~S~;~^~S~;~^~S~>" 'foo) + " foo") + +(my-assert + (format nil "~15<~S~;~^~S~>" 'foo 'bar) + "foo bar") + +(my-assert + (format nil "~15<~S~;~^~S~;~^~S~>" 'foo 'bar) + "foo bar") + +(my-assert + (format nil "~15<~S~;~^~S~;~^~S~>" 'foo 'bar 'baz) + "foo bar baz") + +(my-assert + (format nil "~12<~S~;~^~S~;~^~S~>" 'foo 'bar 'baz) + #+(or CLISP ALLEGRO) "foo bar baz" + #+(OR CMU SBCL) "foo bar baz" + #-(or CLISP ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (progn + (setq liste '(aaaaaaa bbbbbb cccccccccccc dddddddddddddd eeee fffffffff + gggggggg + hhhhh iiii j kk lll mmmm nnnnnn oooooooooo ppppppppppppppp qqqqqqq + rrrrrrrrrrrr + s ttt uuuuuuuuu vvvvvvv wwwwwwwwww xxxxx yyyyyy zzzzzzzz)) ;26 + T) + T) + +(my-assert + (format nil "~%;; ~<~%;; ~1:; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~;~ + ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~;~ + ~s~; ~s~; ~s~; ~s~;~>~%" + ;; 2! + 'aaaaaaa 'bbbbbb 'cccccccccccc 'dddddddddddddd 'eeee 'fffffffff 'gggggggg + 'hhhhh 'iiii 'j 'kk 'lll 'mmmm 'nnnnnn 'oooooooooo 'ppppppppppppppp + 'qqqqqqq + 'rrrrrrrrrrrr 's 'ttt 'uuuuuuuuu 'vvvvvvv 'wwwwwwwwww 'xxxxx 'yyyyyy + 'zzzzzzzz) + #+XCL + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD EEEE FFFFFFFFF GGGGGGGG +;; HHHHH IIII JKK LLL MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ +;; RRRRRRRRRRRR S TTT UUUUUUUUU VVVVVVV WWWWWWWWWW XXXXX +" + ;; 23456789;123456789;123456789;123456789;123456789;123456789;123456789;12 + #-XCL + " +;; +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD EEEE FFFFFFFFF GGGGGGGG HHHHH IIII JKK LLL MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ RRRRRRRRRRRR S TTTUUUUUUUUU VVVVVVV WWWWWWWWWW XXXXX +") + +(my-assert + (format nil "~%;; ~<~%;; ~1,50:; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~;~ + ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~; ~s~;~ + ~s~; ~s~; ~s~; ~s~;~>~%" ; 2! + 'aaaaaaa 'bbbbbb 'cccccccccccc 'dddddddddddddd 'eeee 'fffffffff 'gggggggg + 'hhhhh 'iiii 'j 'kk 'lll 'mmmm 'nnnnnn 'oooooooooo 'ppppppppppppppp + 'qqqqqqq + 'rrrrrrrrrrrr 's 'ttt 'uuuuuuuuu 'vvvvvvv 'wwwwwwwwww 'xxxxx 'yyyyyy + 'zzzzzzzz) + #+XCL + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD +;; EEEE FFFFFFFFF GGGGGGGG HHHHH IIII JKK LLL +;; MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP +;; QQQQQQQ RRRRRRRRRRRR S TTTUUUUUUUUU VVVVVVV +;; WWWWWWWWWW XXXXX +" + ;; 23456789;123456789;123456789;123456789;123456789; + #-XCL + " +;; +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD EEEE FFFFFFFFF GGGGGGGG HHHHH IIII JKK LLL MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ RRRRRRRRRRRR S TTTUUUUUUUUU VVVVVVV WWWWWWWWWW XXXXX +") + +#-sbcl +(my-assert + (defun format-blocksatz (stream parts prefix &optional line-length start-p end-p) + (if (null stream) + (let ((stream (make-string-output-stream))) + (format-blocksatz stream parts prefix line-length start-p end-p) + (get-output-stream-string stream) + ) + (unless (endp parts) + (setq line-length (or line-length #|(sys::line-length stream)|# 72)) + (when start-p (format stream prefix)) + (loop + ;; Hier ist parts /= NIL + (let ((pos (#+CLISP sys::line-position + #+ALLEGRO excl::charpos + #+(OR CMU SBCL) cl::charpos stream)) + (parts-now '())) + (let ((pos-now pos)) + (loop + (when (endp parts) (return)) + (let* ((part (first parts)) + (part-length (length part))) + (unless (null parts-now) + (when (> (+ pos-now part-length) line-length) + (return) + ) ) + (pop parts) + (push part parts-now) + (incf pos-now part-length) + ) ) ) + ;; Hier ist parts-now /= NIL + (apply #'format + stream + (if (and (endp parts) (not end-p)) + (apply #'concatenate 'string + (make-list (length parts-now) :initial-element "~A") + ) + (concatenate 'string + "~" + (write-to-string (max 0 (- line-length pos)) + :radix nil :base 10 + ) + (if (= (length parts-now) 1) "@" "") + "<" + (apply #'concatenate 'string + "~A" + (make-list (1- (length parts-now)) :initial-element "~;~A") + ) + "~>" + ) ) + (nreverse parts-now) + ) ) + (when (endp parts) (return)) + (format stream prefix) + ) ) ) ) + FORMAT-BLOCKSATZ) + +#-sbcl +(my-assert + (format-blocksatz nil + (mapcar #'(lambda (x) (format nil " ~A" x)) + '(aaaaaaa bbbbbb cccccccccccc dddddddddddddd eeee fffffffff + gggggggg hhhhh iiii j kk lll mmmm nnnnnn oooooooooo + ppppppppppppppp qqqqqqq rrrrrrrrrrrr s ttt uuuuuuuuu vvvvvvv + wwwwwwwwww xxxxx yyyyyy zzzzzzzz) + ) + "~%;; " + nil t nil + ) + #+(or CLISP ALLEGRO) + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD EEEE FFFFFFFFF GGGGGGGG +;; HHHHH IIII J KK LLL MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ +;; RRRRRRRRRRRR S TTT UUUUUUUUU VVVVVVV WWWWWWWWWW XXXXX YYYYYY +;; ZZZZZZZZ" + #+(OR CMU SBCL) + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD EEEE FFFFFFFFF GGGGGGGG +;; HHHHH IIII J KK LLL MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ +;; RRRRRRRRRRRR S TTT UUUUUUUUU VVVVVVV WWWWWWWWWW XXXXX YYYYYY +;; ZZZZZZZZ" + #-(or CLISP ALLEGRO cmu sbcl) UNKNOWN) +;; 123456789;123456789;123456789;123456789;123456789;123456789;123456789;12 + +#-sbcl +(my-assert + (format-blocksatz nil + (mapcar #'(lambda (x) (format nil " ~A" x)) + '(aaaaaaa bbbbbb cccccccccccc dddddddddddddd eeee fffffffff + gggggggg hhhhh iiii j kk lll mmmm nnnnnn oooooooooo + ppppppppppppppp qqqqqqq rrrrrrrrrrrr s ttt uuuuuuuuu vvvvvvv + wwwwwwwwww xxxxx yyyyyy zzzzzzzz) + ) + "~%;; " + 50 t t + ) + #+(or CLISP ALLEGRO) + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD +;; EEEE FFFFFFFFF GGGGGGGG HHHHH IIII J KK LLL +;; MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ +;; RRRRRRRRRRRR S TTT UUUUUUUUU VVVVVVV +;; WWWWWWWWWW XXXXX YYYYYY ZZZZZZZZ" + #+(OR CMU SBCL) + " +;; AAAAAAA BBBBBB CCCCCCCCCCCC DDDDDDDDDDDDDD +;; EEEE FFFFFFFFF GGGGGGGG HHHHH IIII J KK LLL +;; MMMM NNNNNN OOOOOOOOOO PPPPPPPPPPPPPPP QQQQQQQ +;; RRRRRRRRRRRR S TTT UUUUUUUUU VVVVVVV +;; WWWWWWWWWW XXXXX YYYYYY ZZZZZZZZ" + #-(or CLISP ALLEGRO cmu sbcl) UNKNOWN) +;; 123456789;123456789;123456789;123456789;123456789; + +;;; unklare Bedeutung (Fehler in Sprachbeschreibung?) +;;; (format nil "~%;; ~{~<~%;; ~1:; ~s~>~^,~}.~%" liste) "" +;;; (format nil "~%;; ~{~<~%;; ~1,50:; ~s~>~^,~}.~%" liste) "" + +(my-assert + (format nil "~%;; ~{~<~%;; ~1,50:; ~s~>~^,~}.~%" + '(aaaaaaa bbbbbb cccccccccccc dddddddddddddd eeee fffffffff + gggggggg hhhhh iiii j kk lll mmmm nnnnnn oooooooooo + ppppppppppppppp qqqqqqq rrrrrrrrrrrr s ttt uuuuuuuuu vvvvvvv + wwwwwwwwww xxxxx yyyyyy zzzzzzzz)) + " +;; AAAAAAA, BBBBBB, CCCCCCCCCCCC, DDDDDDDDDDDDDD, +;; EEEE, FFFFFFFFF, GGGGGGGG, HHHHH, IIII, J, KK, +;; LLL, MMMM, NNNNNN, OOOOOOOOOO, +;; PPPPPPPPPPPPPPP, QQQQQQQ, RRRRRRRRRRRR, S, +;; TTT, UUUUUUUUU, VVVVVVV, WWWWWWWWWW, XXXXX, +;; YYYYYY, ZZZZZZZZ. +") + +;; ~f ------------------------------------------------------------------------ +;; Format F + +(my-assert + (DEFUN FOO (X) + (FORMAT NIL "~6,2F|~6,2,1,'*F|~6,2,,'?F|~6F|~,2F|~F" X X X X + X X)) + FOO) + +(my-assert + (FOO 3.14159) + ;; " 3.14| 31.42| 3.14|3.1416|3.14|3.141590116672995328" + " 3.14| 31.42| 3.14|3.1416|3.14|3.14159") + +(my-assert + (FOO -3.14159) + ;; " -3.14|-31.42| -3.14|-3.142|-3.14|-3.141590116672995328" + " -3.14|-31.42| -3.14|-3.142|-3.14|-3.14159") + +(my-assert + (FOO 100.0) + "100.00|******|100.00| 100.0|100.00|100.0") + +(my-assert + (FOO 1234.0) + "1234.00|******|??????|1234.0|1234.00|1234.0") + +(my-assert + (FOO 0.006) + " 0.01| 0.06| 0.01| 0.006|0.01|0.006") + +(my-assert + (format nil "~5,2,-13f" 1.1e13) + " 1.10") + +(my-assert + (format nil "~9,0,6f" 3.14159) + " 3141590.") + +(my-assert + (FORMAT NIL "~5D" (QUOTE A)) + " A" + "ANSI CL is not clear here whether the width is ignored or not, +but it makes more sense to print non-numeric arguments properly alighned") + +(my-assert + (FORMAT NIL "~5,3F" (QUOTE A)) + " A" + "ANSI CL is not clear here whether the width is ignored or not, +but it makes more sense to print non-numeric arguments properly alighned") + +(my-assert + (FORMAT NIL "~5,3F" #C(1.2 0.3)) + "#C(1.2 0.3)") + +(my-assert + (FORMAT NIL "~5,3F" 2/3) + "0.667") + +;; ~e ----------------------------- ------------------------------------------ +;; Format E + +(my-assert + (defun foo (x) + (format nil + "~9,2,1,,'*E|~10,3,2,2,'?,,'$E|~9,3,2,-2,'%@e|~9,2E" + x x x x)) + FOO) + +(my-assert + (foo 3.14159) + " 3.14E+0| 31.42$-01|+.003E+03| 3.14E+0") + +(my-assert + (foo -3.14159) + " -3.14E+0|-31.42$-01|-.003E+03| -3.14E+0") + +(my-assert + (foo 1100.0) + " 1.10E+3| 11.00$+02|+.001E+06| 1.10E+3") + +(my-assert + (foo 1100.0L0) + #+XCL " 1.10D+3| 11.00$+02|+.001D+06| 1.10D+3" + #+(or CLISP AKCL) " 1.10L+3| 11.00$+02|+.001L+06| 1.10L+3" + #+(or ALLEGRO cmu sbcl) " 1.10d+3| 11.00$+02|+.001d+06| 1.10d+3" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (foo 1.1E13) + "*********| 11.00$+12|+.001E+16| 1.10E+13") + +;; ERROR beim read der zahl (foo 1.1L120) + +(my-assert + (FORMAT NIL "_~10,4E_" 1.2) + "_ 1.2000E+0_") + +(my-assert + (format nil "~9,2,1E" 0.0314159) + " 3.14E-2") + +;; ~% ~d ~e (v) -------------------------------------------------------------- +(my-assert + (let (x) + (dotimes (k 13 x) + (setq x (cons (format nil "~%Scale factor ~2D: |~13,6,2,VE|" + (- k 5) (- k 5) 3.14159) x)))) + ( + " +Scale factor 7: | 3141590.E-06|" " +Scale factor 6: | 314159.0E-05|" " +Scale factor 5: | 31415.90E-04|" " +Scale factor 4: | 3141.590E-03|" " +Scale factor 3: | 314.1590E-02|" " +Scale factor 2: | 31.41590E-01|" " +Scale factor 1: | 3.141590E+00|" " +Scale factor 0: | 0.314159E+01|" " +Scale factor -1: | 0.031416E+02|" " +Scale factor -2: | 0.003142E+03|" " +Scale factor -3: | 0.000314E+04|" " +Scale factor -4: | 0.000031E+05|" " +Scale factor -5: | 0.000003E+06|")) + + +;; ~g ------------------------------------------------------------------------ +(my-assert + (defun foo (x) + (format nil "~9,2,1,,'*G|~9,3,2,3,'?,,'$G|~9,3,2,0,'%G|~9,2G" + x x x x)) + foo) + +(my-assert + (foo 0.0314159) + " 3.14E-2|314.2$-04|0.314E-01| 3.14E-2") + +(my-assert + (foo 0.314159) + " 0.31 |0.314 |0.314 | 0.31 ") + +(my-assert + (foo 3.14159) + " 3.1 | 3.14 | 3.14 | 3.1 ") + +(my-assert + (foo 31.4159) + " 31. | 31.4 | 31.4 | 31. ") + +(my-assert + (foo 314.159) + " 3.14E+2| 314. | 314. | 3.14E+2") + +(my-assert + (foo 3141.59) + " 3.14E+3|314.2$+01|0.314E+04| 3.14E+3") + +(my-assert + (foo 3141.59L0) + #+XCL " 3.14D+3|314.2$+01|0.314D+04| 3.14D+3" + #+(or CLISP AKCL) " 3.14L+3|314.2$+01|0.314L+04| 3.14L+3" + #+(or ALLEGRO cmu sbcl) " 3.14d+3|314.2$+01|0.314d+04| 3.14d+3" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (foo 3.14E12) + "*********|314.0$+10|0.314E+13| 3.14E+12") + +;; (foo 3.14L120 und L1200) fehler in numerik + +;; ~a ------------------------------------------------------------------------ + +(my-assert + (FORMAT NIL "foo") + "foo") + +(my-assert + (FORMAT NIL "format-a:--~a--ende" (QUOTE AB\c)) + "format-a:--ABc--ende") + +(my-assert + (SETQ Y "elephant") + "elephant") + +(my-assert + (FORMAT NIL "Look at the ~A!" Y) + "Look at the elephant!") + +(my-assert + (FORMAT NIL "format-%:--~%--1-newline-*") + "format-%:-- +--1-newline-*") + +(my-assert + (FORMAT NIL "format-%:--~3%--3-newline-*") + "format-%:-- + + +--3-newline-*") + +(my-assert + (FORMAT NIL "format-a:--~5a--ende-*" (QUOTE AB\c)) + "format-a:--ABc --ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2a--ende-*" (QUOTE AB\c)) + "format-a:--ABc --ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2,3a--ende-*" (QUOTE AB\c)) + "format-a:--ABc --ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2,3,'*a--ende-*" (QUOTE AB\c)) + "format-a:--ABc***--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~@a--ende-*" (QUOTE AB\c)) + "format-a:--ABc--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5@a--ende-*" (QUOTE AB\c)) + "format-a:-- ABc--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2@a--ende-*" (QUOTE AB\c)) + "format-a:-- ABc--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2,3@a--ende-*" (QUOTE AB\c)) + "format-a:-- ABc--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~5,2,3,'*@a--ende-*" (QUOTE AB\c)) + "format-a:--***ABc--ende-*") + +(my-assert + (FORMAT NIL "format-a:--~:a--ende-*" (QUOTE (AB\c NIL XYZ))) + "format-a:--(ABc NIL XYZ)--ende-*") + +(my-assert + (FORMAT NIL "format-s:--~s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c --ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c --ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2,3s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c --ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc| --ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2,3,'*s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c***--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|***--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~@s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5@s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:-- AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2@s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:-- AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2,3@s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:-- AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:-- |ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~5,2,3,'*@s--ende-*" (QUOTE AB\c)) + #+XCL "format-s:--***AB\\c--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--***|ABc|--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (FORMAT NIL "format-s:--~:s--ende-*" (QUOTE (AB\c NIL XYZ))) + #+XCL "format-s:--(AB\\c NIL XYZ)--ende-*" + #+(or CLISP AKCL ALLEGRO cmu sbcl) "format-s:--(|ABc| NIL XYZ)--ende-*" + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl) UNKNOWN) + +(my-assert + (SETQ X 5) + 5) + +(my-assert + (FORMAT NIL "The answer is ~D." X) + "The answer is 5.") + +(my-assert + (FORMAT NIL "The answer is ~3D." X) + "The answer is 5.") + +(my-assert + (FORMAT NIL "The answer is ~3,'0D." X) + "The answer is 005.") + +(my-assert + (FORMAT NIL "The answer is ~:D." (EXPT 47 X)) + "The answer is 229,345,007.") + +(my-assert + (FORMAT NIL "decimal:~d, width=5:~5d-*" 10 10) + "decimal:10, width=5: 10-*") + +(my-assert + (FORMAT NIL "format-d:--~d--ende-*" 123) + "format-d:--123--ende-*") + +(my-assert + (FORMAT NIL "format-d:--~10d--ende-*" 123) + "format-d:-- 123--ende-*") + +(my-assert + (FORMAT NIL "format-d:--~10,'?d--ende-*" 123) + "format-d:--???????123--ende-*") + +(my-assert + (FORMAT NIL "format-d:--~@d--ende-*" 123) + "format-d:--+123--ende-*") + +(my-assert + (FORMAT NIL "format-d:--~10@d--ende-*" 123) + "format-d:-- +123--ende-*") + +(my-assert + (FORMAT NIL "format-d:--~10,'?@d--ende-*" 123) + "format-d:--??????+123--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~b--ende-*" 123) + "format-b:--1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10b--ende-*" 123) + "format-b:-- 1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10,'?b--ende-*" 123) + "format-b:--???1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~:b--ende-*" 123) + "format-b:--1,111,011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10:b--ende-*" 123) + "format-b:-- 1,111,011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10,'?:b--ende-*" 123) + "format-b:--?1,111,011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10,'?,'.:b--ende-*" 123) + "format-b:--?1.111.011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~@b--ende-*" 123) + "format-b:--+1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10@b--ende-*" 123) + "format-b:-- +1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~10,'?@b--ende-*" 123) + "format-b:--??+1111011--ende-*") + +(my-assert + (FORMAT NIL "format-b:--~:@b--ende-*" 123) + "format-b:--+1,111,011--ende-*") + +(my-assert + (FORMAT NIL "format-o:--~o--ende-*" 123) + "format-o:--173--ende-*") + +(my-assert + (FORMAT NIL "format-o:--~10o--ende-*" 123) + "format-o:-- 173--ende-*") + +(my-assert + (FORMAT NIL "format-o:--~10,'?o--ende-*" 123) + "format-o:--???????173--ende-*") + +(my-assert + (FORMAT NIL "format-o:--~@o--ende-*" 123) + "format-o:--+173--ende-*") + +(my-assert + (FORMAT NIL "format-o:--~10@o--ende-*" 123) + "format-o:-- +173--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~x--ende-*" 123) + "format-x:--7B--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~10x--ende-*" 123) + "format-x:-- 7B--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~10,'?x--ende-*" 123) + "format-x:--????????7B--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~10:x--ende-*" 123) + "format-x:-- 7B--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~@x--ende-*" 123) + "format-x:--+7B--ende-*") + +(my-assert + (FORMAT NIL "format-x:--~10@x--ende-*" 123) + "format-x:-- +7B--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~20r--ende-*" 123) + "format-r:--63--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~20,10r--ende-*" 123) + "format-r:-- 63--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~20@r--ende-*" 123) + "format-r:--+63--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~r--ende-*" 9) + "format-r:--nine--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~:r--ende-*" 9) + "format-r:--ninth--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~@r--ende-*" 9) + "format-r:--IX--ende-*") + +(my-assert + (FORMAT NIL "format-r:--~:@r--ende-*" 9) + "format-r:--VIIII--ende-*") + +(my-assert + (FORMAT NIL "format-p:--~d object~p-*" 1 1) + "format-p:--1 object-*") + +(my-assert + (FORMAT NIL "format-p:--~d object~p-*" 2 2) + "format-p:--2 objects-*") + +(my-assert + (FORMAT NIL "format-p:--~d bab~@p-*" 1 1) + "format-p:--1 baby-*") + +(my-assert + (FORMAT NIL "format-p:--~d bab~@p-*" 2 2) + "format-p:--2 babies-*") + +(my-assert + (FORMAT NIL "format-p:--~d object~:p-*" 1) + "format-p:--1 object-*") + +(my-assert + (FORMAT NIL "format-p:--~d object~:p-*" 2) + "format-p:--2 objects-*") + +(my-assert + (FORMAT NIL "format-p:--~d bab~:@p-*" 1) + "format-p:--1 baby-*") + +(my-assert + (FORMAT NIL "format-&:--~%~&--1-newline-*") + "format-&:-- +--1-newline-*") + +(my-assert + (FORMAT NIL "format-&:--~%~3&--3-newline-*") + "format-&:-- + + +--3-newline-*") + +(my-assert + (FORMAT NIL "format-tilde:--~~--1-tilde-*") + "format-tilde:--~--1-tilde-*") + +(my-assert + (FORMAT NIL "format-tilde:--~3~--3-tilden-*") + "format-tilde:--~~~--3-tilden-*") + +(my-assert + (FORMAT NIL "format-|:--~|--1-ff-*") + "format-|:-- --1-ff-*") + +(my-assert + (FORMAT NIL "format-|:--~2|--2-ff-*") + "format-|:-- --2-ff-*") + +(my-assert + (FORMAT NIL + "format-:~ + gl. zeile gl. angeschlossen trotz 2* und sp-*") + "format-:gl. zeile gl. angeschlossen trotz 2* und sp-*") + +(my-assert + (FORMAT NIL "format-:~@ + neue Zeile Anfang trotz + sp-*") + "format-: +neue Zeile Anfang trotz + sp-*") + +(my-assert + (FORMAT NIL "format-:~: + gleiche Zeile aber ein tab vor Anfang-*") + "format-: gleiche Zeile aber ein tab vor Anfang-*") + +(my-assert + (FORMAT NIL "format-?:***~a***~?***~a***-*" 1 "+++~s+++~s+++" (QUOTE + (A B)) 2) + "format-?:***1***+++A+++B+++***2***-*") + +(my-assert + (FORMAT NIL "format-?:***~a***~?***~a***-*" 1 "+++++++++++++" NIL 2) + "format-?:***1***+++++++++++++***2***-*") + +(my-assert + (FORMAT NIL "~(AAAAAAAA BBBBBB ccccccc dddddddd~)") + "aaaaaaaa bbbbbb ccccccc dddddddd") + +(my-assert + (FORMAT NIL "~:(AAAAAAAA BBBBBB ccccccc dddddddd~)") + "Aaaaaaaa Bbbbbb Ccccccc Dddddddd") + +(my-assert + (FORMAT NIL "~@(AAAAAAAA BBBBBB ccccccc dddddddd~)") + "Aaaaaaaa bbbbbb ccccccc dddddddd") + +(my-assert + (FORMAT NIL "~:@(AAAAAAAA BBBBBB ccccccc dddddddd~)") + "AAAAAAAA BBBBBB CCCCCCC DDDDDDDD") + +(my-assert + (FORMAT NIL "++~{-=~s=-~}++" (QUOTE (1 2 3))) + "++-=1=--=2=--=3=-++") + +(my-assert + (FORMAT NIL "++~2{-=~s=-~}++" (QUOTE (1 2 3))) + "++-=1=--=2=-++") + +(my-assert + (FORMAT NIL "++~@{-=~s=-~}++" 1 2 3) + "++-=1=--=2=--=3=-++") + +(my-assert + (FORMAT NIL "++~:{-=~s=~s=-~}++" (QUOTE ((1 2) (3 4 5) (6 7)))) + "++-=1=2=--=3=4=--=6=7=-++") + +(my-assert + (FORMAT NIL "++~:@{-=~s=~s=-~}++" (QUOTE (1 2)) (QUOTE (3 4 5)) (QUOTE + (6 7))) + "++-=1=2=--=3=4=--=6=7=-++") + +(my-assert + (FORMAT NIL "~{abc~:}") + #+XCL "abc" + #-XCL ERROR) + +(my-assert + (FORMAT NIL "~{~:}" "xyz") + #+XCL "xyz" + #-XCL ERROR) + +(my-assert + (FORMAT NIL "~1{~:}" "-~s-" (QUOTE (1 2)) 3) + "-1-") + +(my-assert + (FORMAT NIL "123456789012345678901234567890 +~10,4txx~10,4ty~10,4tzzz~10,4tende") + #+XCL + "123456789012345678901234567890 + xx y zzz ende" + #-XCL + "123456789012345678901234567890 + xx y zzz ende") + +(my-assert + (FORMAT NIL "123456789012345678901234567890 +~3,4@txx~3,4@ty~3,4@tzzz~3,4@tende") + #+XCL + "123456789012345678901234567890 + xx y zzz ende" + #-XCL + "123456789012345678901234567890 + xx y zzz ende") + +(my-assert + (FORMAT NIL "-~a-~a-~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-3-4-") + +(my-assert + (FORMAT NIL "-~a-~a-~*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-4-5-") + +(my-assert + (FORMAT NIL "-~a-~a-~3*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-6-7-") + +(my-assert + (FORMAT NIL "-~a-~a-~:*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-2-3-") + +(my-assert + (FORMAT NIL "-~a-~a-~2:*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-1-2-") + +(my-assert + (FORMAT NIL "-~a-~a-~@*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-1-2-") + +(my-assert + (FORMAT NIL "-~a-~a-~6@*~a-~a-" 1 2 3 4 5 6 7 8 9) + "-1-2-7-8-") + +(my-assert + (FORMAT NIL "~[aa~;bb~;cc~]" 1) + "bb") + +(my-assert + (FORMAT NIL "~[aa~;bb~;cc~]" 10) + "") + +(my-assert + (FORMAT NIL "~2[aa~;bb~;cc~]" 10) + "cc") + +(my-assert + (FORMAT NIL "~@[aaa~]" NIL 10) + "") + +(my-assert + (FORMAT NIL "~@[aaa~]" 20 10) + "aaa") + +(my-assert + (FORMAT NIL "~@[aaa~d~]" NIL 10) + "") + +(my-assert + (FORMAT NIL "~@[aaa~d~]" 20 10) + "aaa20") + +(my-assert + (FORMAT NIL "~@[aaa~d~]bbb~d" NIL 10 30) + "bbb10") + +(my-assert + (FORMAT NIL "~@[aaa~d~]bbb~d" 20 10 30) + "aaa20bbb10") + +(my-assert + (FORMAT NIL "~:[-nil-~;-true-~d~]-ende~d" NIL 10 20) + "-nil--ende10") + +(my-assert + (FORMAT NIL "~:[-nil-~;-true-~d~]-ende~d" T 10 20) + "-true-10-ende20") + +(my-assert + (FORMAT NIL "Start test, newline:~%freshline:~&") + "Start test, newline: +freshline: +") + +(my-assert + (FORMAT NIL "decimal pad with period:~10,vd-*" #\. 12) + "decimal pad with period:........12-*") + +(my-assert + (FORMAT NIL "char normal:~c, as ~%# would read:~%~@c, human read:~:c-*" + #\SPACE + #\SPACE #\SPACE) + #+(or XCL cmu sbcl CLISP) "char normal: , as +# would read: +#\\Space, human read:Space-*" + #+(or AKCL LUCID) "char normal:Space, as +# would read: +#\\Space, human read:Space-*" + #+ALLEGRO "char normal: , as +# would read: +#\\space, human read:space-*" + #-(or XCL cmu sbcl CLISP AKCL LUCID ALLEGRO) UNKNOWN) + +(my-assert + (FORMAT NIL + "cardinal:~r, roman new:~@r, roman-old:~:@r~ + ~@ + new line but at beginning~: + same line, but spaced out~@ + new line and over two tabs-*" 4 4 4) + "cardinal:four, roman new:IV, roman-old:IIII +new line but at beginning same line, but spaced out +new line and over two tabs-*") + +(my-assert + (SETQ N 3) + 3) + +(my-assert + (FORMAT NIL "~D item~:P found." N) + "3 items found.") + +(my-assert + (FORMAT NIL "~R dog~:[s are~; is~] here." N (= N 1)) + "three dogs are here.") + +(my-assert + (FORMAT NIL "~R dog~:*~[s are~; is~:;s are~] here." N) + "three dogs are here.") + +(my-assert + (FORMAT NIL "Here ~[are~;is~:;are~] ~:*~R pupp~:@p." N) + "Here are three puppies.") + +(my-assert + (SETQ N 1) + 1) + +(my-assert + (FORMAT NIL "~D item~:P found." N) + "1 item found.") + +(my-assert + (FORMAT NIL "~R dog~:[s are~; is~] here." N (= N 1)) + "one dog is here.") + +(my-assert + (FORMAT NIL "~R dog~:*~[s are~; is~:;s are~] here." N) + "one dog is here.") + +(my-assert + (FORMAT NIL "Here ~[are~;is~:;are~] ~:*~R pupp~:@p." N) + "Here is one puppy.") + +(my-assert + (SETQ N 0) + 0) + +(my-assert + (FORMAT NIL "~D item~:P found." N) + "0 items found.") + +(my-assert + (FORMAT NIL "~R dog~:[s are~; is~] here." N (= N 1)) + "zero dogs are here.") + +(my-assert + (FORMAT NIL "~R dog~:*~[s are~; is~:;s are~] here." N) + "zero dogs are here.") + +(my-assert + (FORMAT NIL "Here ~[are~;is~:;are~] ~:*~R pupp~:@p." N) + "Here are zero puppies.") + +(my-assert + (FORMAT NIL "~D tr~:@p/~D win~:P" 7 1) + "7 tries/1 win") + +(my-assert + (FORMAT NIL "~D tr~:@p/~D win~:P" 1 0) + "1 try/0 wins") + +(my-assert + (FORMAT NIL "~D tr~:@p/~D win~:P" 1 3) + "1 try/3 wins") + +(my-assert + (DEFUN TYPE-CLASH-ERROR (FN NARGS ARGNUM RIGHT-TYPE WRONG-TYPE) (FORMAT + NIL + "~&~S requires itts ~:[~:R~;~*~] ~ + argument to be of type ~S,~%but it was called ~ + with an argument of type ~S.-*" FN (EQL NARGS 1) ARGNUM + RIGHT-TYPE + WRONG-TYPE)) + TYPE-CLASH-ERROR) + +(my-assert + (TYPE-CLASH-ERROR (QUOTE AREF) NIL 2 (QUOTE INTEGER) (QUOTE VECTOR)) + "AREF requires itts second argument to be of type INTEGER, +but it was called with an argument of type VECTOR.-*") + +(my-assert + (TYPE-CLASH-ERROR (QUOTE CAR) 1 1 (QUOTE LIST) (QUOTE SHORT-FLOAT)) + "CAR requires itts argument to be of type LIST, +but it was called with an argument of type SHORT-FLOAT.-*") + +(my-assert + (FORMAT NIL "~? ~D" "<~A ~D>" (QUOTE ("Foo" 5)) 7) + " 7") + +(my-assert + (FORMAT NIL "~? ~D" "<~A ~D>" (QUOTE (" Foo" 5 14)) 7) + "< Foo 5> 7") + +(my-assert + (FORMAT NIL "~@? ~d" "<~A ~D>" "Foo" 5 7) + " 7") + +(my-assert + (FORMAT NIL "~@? ~D" "<~A ~D>" "Foo" 5 14 7) + " 14") + +(my-assert + (FORMAT NIL "~@R ~(~@R~)" 14 14) + "XIV xiv") + +(my-assert + (DEFUN F (N) (FORMAT NIL "~@(~R~) error~:P detected." N)) + F) + +(my-assert + (F 0) + "Zero errors detected.") + +(my-assert + (F 1) + "One error detected.") + +(my-assert + (F 23) + "Twenty-three errors detected.") + +(my-assert + (SETQ *PRINT-LEVEL* NIL *PRINT-LENGTH* 5) + 5) + +(my-assert + (FORMAT NIL "~@[ print level = ~D~]~@[ print length = ~D~]" *PRINT-LEVEL* + + *PRINT-LENGTH*) + " print length = 5") + +(my-assert + (SETQ *PRINT-LENGTH* NIL) + NIL) + +(my-assert + (SETQ FOO + "Items:~#[none~; ~s~; ~S and ~S~ + ~:;~@{~#[~; and~] ~S~^,~}~].") + "Items:~#[none~; ~s~; ~S and ~S~ + ~:;~@{~#[~; and~] ~S~^,~}~].") + +(my-assert + (FORMAT NIL FOO) + "Items:none.") + +(my-assert + (FORMAT NIL FOO (QUOTE FOO)) + "Items: FOO.") + +(my-assert + (FORMAT NIL FOO (QUOTE FOO) (QUOTE BAR)) + "Items: FOO and BAR.") + +(my-assert + (FORMAT NIL FOO (QUOTE FOO) (QUOTE BAR) (QUOTE BAZ)) + "Items: FOO, BAR, and BAZ.") + +(my-assert + (FORMAT NIL FOO (QUOTE FOO) (QUOTE BAR) (QUOTE BAZ) (QUOTE QUUX)) + "Items: FOO, BAR, BAZ, and QUUX.") + +(my-assert + (FORMAT NIL "The winners are:~{ ~S~}." (QUOTE (FRED HARRY JILL))) + "The winners are: FRED HARRY JILL.") + +(my-assert + (FORMAT NIL "Pairs:~{ <~S,~S>~}." (QUOTE (A 1 B 2 C 3))) + "Pairs: .") + +(my-assert + (FORMAT NIL "Pairs:~:{ <~S,~S>~}." (QUOTE ((A 1) (B 2) (C 3)))) + "Pairs: .") + +(my-assert + (FORMAT NIL "Pairs:~@{ <~S,~S>~}." (QUOTE A) 1 (QUOTE B) 2 (QUOTE C) + 3) + "Pairs: .") + +(my-assert + (FORMAT NIL "Pairs:~:@{ <~S,~S>~}." (QUOTE (A 1)) (QUOTE (B 2)) (QUOTE + (C 3))) + "Pairs: .") + +(my-assert + (SETQ DONESTR "done.~^ ~D warning~:P.~^ ~D error~:P.") + "done.~^ ~D warning~:P.~^ ~D error~:P.") + +(my-assert + (FORMAT NIL DONESTR) + "done.") + +(my-assert + (FORMAT NIL DONESTR 3) + "done. 3 warnings.") + +(my-assert + (FORMAT NIL DONESTR 1 5) + "done. 1 warning. 5 errors.") + +(my-assert + (SETQ TELLSTR "~@(~@[~R~]~^ ~A.~)") + "~@(~@[~R~]~^ ~A.~)") + +(my-assert + (FORMAT NIL TELLSTR 23) + "Twenty-three") + +(my-assert + (FORMAT NIL TELLSTR NIL "losers") + " Losers.") + +(my-assert + (FORMAT NIL TELLSTR 23 "losers") + "Twenty-three losers.") + +(my-assert + (FORMAT NIL "**~c**" #\SPACE) + #+(or XCL cmu sbcl CLISP ALLEGRO) "** **" + #+(or AKCL LUCID) "**Space**" + #-(or XCL cmu sbcl CLISP AKCL LUCID ALLEGRO) UNKNOWN) + +(my-assert + (FORMAT NIL "**~:c**" #\SPACE) + "**Space**") + +(my-assert + (FORMAT NIL "**~:@c**" #\SPACE) + "**Space**") + +(my-assert + (FORMAT NIL "**~@c**" #\SPACE) + "**#\\Space**") + +(my-assert + (FORMAT NIL "**~c**" #\A) + "**A**") + +(my-assert + (FORMAT NIL "**~:c**" #\A) + "**A**") + +(my-assert + (FORMAT NIL "**~:@c**" #\A) + "**A**") + +(my-assert + (FORMAT NIL "**~@c**" #\A) + "**#\\A**") + +#+XCL +(my-assert + (FORMAT NIL "**~c**" (CODE-CHAR 26)) + "****") + +#+clisp +(my-assert + (FORMAT NIL "**~c**" (CODE-CHAR 27)) + "****") + +#+XCL +(my-assert + (FORMAT NIL "**~:c**" (CODE-CHAR 26)) + "**Z**") + +#+clisp +(my-assert + (FORMAT NIL "**~:c**" (CODE-CHAR 27)) + "**Escape**") + +#+XCL +(my-assert + (FORMAT NIL "**~:@c**" (CODE-CHAR 26)) + "**^Z**") + +#+clisp +(my-assert + (FORMAT NIL "**~:@c**" (CODE-CHAR 27)) + "**Escape**") + +#+XCL +(my-assert + (FORMAT NIL "**~@c**" (CODE-CHAR 26)) + "**#\\**") + +#+clisp +(my-assert + (FORMAT NIL "**~@c**" (CODE-CHAR 27)) + "**#\\Escape**") + +(my-assert + (progn (fmakunbound 'foo) + (makunbound 'liste) + t) + T) + diff --git a/src/ansi-tests/hash.lisp b/src/ansi-tests/hash.lisp new file mode 100644 index 000000000..188d7d95e --- /dev/null +++ b/src/ansi-tests/hash.lisp @@ -0,0 +1,269 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (progn (in-package (quote sys)) t) t) + +(my-assert + (make-hash-table :test (quote eq) :size 20) + #s(hash-table test eq size 20 %%size 64 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :test (quote eql) :size 2) + #s(hash-table test eql size 2 %%size 4 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 2 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :test (quote equal) :size 2) + #s(hash-table test equal size 2 %%size 4 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 2 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (progn (make-hash-table :test (function eq) :size 2) t) t) + +(my-assert + (progn (make-hash-table :test (function eql) :size 2)t) t) + +(my-assert + (make-hash-table :size nil) + error) + +(my-assert + (make-hash-table :size -3) + error) + +(my-assert + (make-hash-table :size 2.0) + error) + +(my-assert + (make-hash-table :size 2 :rehash-size 1.5) + #s(hash-table test eql size 2 %%size 4 rehash-size 1.5 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 2 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :size 2 :rehash-size -1.5) + error) + +(my-assert + (make-hash-table :size 2 :rehash-size 0.5) + error) + +(my-assert + (make-hash-table :size 2 :rehash-size 1.0) + #s(hash-table test eql size 2 %%size 4 rehash-size 1.0 %%rehash-size 4 + rehash-threshold 13 %%rehash-threshold 2 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :size 2 :rehash-size 5) + #s(hash-table test eql size 2 %%size 4 rehash-size 5 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 2 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :size 4 :rehash-size 5.0) + #s(hash-table test eql size 4 %%size 8 rehash-size 5.0 %%rehash-size 8 + rehash-threshold 13 %%rehash-threshold 3 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element))) + +(my-assert + (make-hash-table :size 2 :rehash-size nil) + error) + +(my-assert + (make-hash-table :size 2 :rehash-threshold nil) + error) + +(my-assert + (make-hash-table :%%size 3) + #s(hash-table test eql size 16 %%size 3 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element))) + +(my-assert + (setq tab (make-hash-table)) + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + +(my-assert + (setf-gethash (quote hallo) tab (quote wiegwhts)) + wiegwhts) + +(my-assert + (setf-gethash (quote uhu) tab (quote kauz)) + kauz) + +(my-assert + (gethash (quote uhu) tab) + kauz) + +(my-assert + (gethash uhu tab) + error) + +(my-assert + (make-hash-table) + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + +(my-assert + (setq tab nil) + nil) + +(my-assert + (setf-gethash (quote uhu) tab (quote kaus)) + error) + +(my-assert + (gethash (quote uhu) tab) + error) + +(my-assert + (gethash (quote otto) tab) + error) + +(my-assert + (setq tab (make-hash-table)) + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + +(my-assert + (setf-gethash (quote uhu) tab (quote kaus)) + kaus) + +(my-assert + (gethash (quote uhu) tab) + kaus) + +(my-assert + (gethash (quote otto) tab) + nil) + +(my-assert + (setf-gethash (quote uhu) tab (quote kauz)) + kauz) + +(my-assert + (setf-gethash tab) + error) + +(my-assert + (remhash (quote uhu) tab) + t) + +(my-assert + tab + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + +(my-assert + (clrhash tab9) + error) + +(my-assert + (clrhash tab) + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + +(my-assert + (hash-table-count tab) + 0) + +(my-assert + (setf-gethash (quote klak) tab (quote klase)) + klase) + +(my-assert + (setf-gethash (quote kunze) tab (quote riese)) + riese) + +(my-assert + (hash-table-p tab) + t) + +(my-assert + (hash-table-count tab) + 2) + +(my-assert + (remhash (quote kunze) tab) + t) + +(my-assert + (setf-gethash (quote wald) tab (quote khjgsfgjhdf)) + khjgsfgjhdf) + +(my-assert + (gethash) + error) + +(my-assert + (remhash) + error) + +(my-assert + (clrhash tab) + #s(hash-table test eql size 16 %%size 32 rehash-size 2.0 %%rehash-size 2 + rehash-threshold 13 %%rehash-threshold 13 %%count 0 %%hash-vektor + #(%%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element %%empty-element %%empty-element + %%empty-element %%empty-element %%empty-element))) + diff --git a/src/ansi-tests/hashlong.lisp b/src/ansi-tests/hashlong.lisp new file mode 100644 index 000000000..ce6e46826 --- /dev/null +++ b/src/ansi-tests/hashlong.lisp @@ -0,0 +1,63 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +#+clisp +(setf (symbol-function 'setf-gethash) + (symbol-function 'sys::puthash)) + +#+(or akcl ecls) +(setf (symbol-function 'setf-gethash) + (symbol-function 'sys:hash-set)) t +#+allegro +(setf (symbol-function 'setf-gethash) + (symbol-function 'excl::%puthash)) t +#+cmu +(setf (symbol-function 'setf-gethash) + (symbol-function 'cl::%puthash)) t +#+sbcl +(setf (symbol-function 'setf-gethash) + (symbol-function 'sb-impl::%puthash)) t + +(my-assert + (defun symbole () + (let ((b 0.) + (hash-table (make-hash-table :size 20. + :rehash-threshold + #+xcl 15. + #-xcl 0.75)) + (liste (make-list 50.)) + (liste2 (make-list 50.))) + (rplacd (last liste) liste) + (rplacd (last liste2) liste2) + (do-symbols (x (find-package #+xcl 'lisptest + #-xcl "LISP")) + ;; (print x) (finish-output) + (cond ((car liste) + (let ((hval (gethash (car liste) hash-table)) + (lval (car liste2))) + (unless (eq hval lval) + (print "mist, hash-tabelle kaputt") + (print (car liste)) + (print hash-table) + (print (hash-table-count hash-table)) + (print "hval:") (print hval) + (print "lval:") (print lval) + (return-from symbole 'error)) + (remhash (car liste) hash-table) + #+xcl (when (< (room) 30000.) (system::%garbage-collection)) + (setf-gethash x hash-table (setq b (+ 1. b))) + (rplaca liste x) + (rplaca liste2 b) + (setq liste (cdr liste)) + (setq liste2 (cdr liste2)))) + (t (setf-gethash x hash-table (setq b (+ 1. b))) + (rplaca liste x) + (rplaca liste2 b) + (setq liste (cdr liste)) + (setq liste2 (cdr liste2))))))) + symbole) + + +(my-assert + (symbole) nil) + diff --git a/src/ansi-tests/iofkts.lisp b/src/ansi-tests/iofkts.lisp new file mode 100644 index 000000000..295832bd5 --- /dev/null +++ b/src/ansi-tests/iofkts.lisp @@ -0,0 +1,967 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) + +;; **************************************************************************** +;; * test der i/o-funktionen * +;; **************************************************************************** + +#+xcl +(my-assert + (progn (in-package (quote sys)) t) + t) + +;; --- let test --------------------------------------------------------------- +;; ewiger compiler-fehler +;; + +(my-assert + (progn (setq bs (make-broadcast-stream)) t) + t) + +#+xcl +(my-assert + *cur-broadcast-stream* + nil) + +(my-assert + (print 123. bs) + 123.) + +#+xcl +(my-assert + *cur-broadcast-stream* + nil) + +;; ------------------------------------------------------------------------------- +;; unread test mit structure-stream +;; + +(my-assert + (setq str1 "test 123456") "test 123456") + +(my-assert + (progn (setq s1 (make-two-way-stream (make-string-input-stream str1) + *standard-output*)) t) + t) + +(my-assert + (read s1) test) + +(my-assert + (read-char s1) #\1) + +(my-assert + (read-char s1) #\2) + +(my-assert + (unread-char #\2 s1) nil) + +(my-assert + (read-char s1) #\2) + +(my-assert + (read-char s1) #\3) + +(my-assert + (read-char s1) #\4) + +(my-assert + (unread-char #\a s1) error + "I just read #\4 I cannot put #\a back") + +(my-assert + (read-char s1) #\5 "The last unread should have failed, we're +out of sync") + +(my-assert + (read-char s1) #\6 "still out of sync?") + +(my-assert + (close s1) t) + +(my-assert + str1 "test 123456") + + +;; ------------------------------------------------------------------------------- + +(my-assert + (multiple-value-list (parse-integer "abc")) + error) + +(my-assert + (multiple-value-list (parse-integer " abc ")) + error) + +(my-assert + (multiple-value-list (parse-integer "123")) + (123 3)) + +(my-assert + (multiple-value-list (parse-integer " 123 ")) + #-(or cmu sbcl) + (123 7) + #+(or cmu sbcl) + (123 5)) + +(my-assert + (multiple-value-list (parse-integer "123 t")) + error) + +(my-assert + (multiple-value-list (parse-integer " 123 t ")) + error) + +(my-assert + (multiple-value-list (parse-integer " ( 12 ) 43 t ")) + error) + +(my-assert + (multiple-value-list (parse-integer " abc " :junk-allowed t)) + (nil 2)) + +(my-assert + (multiple-value-list (parse-integer "123" :junk-allowed t)) + (123 3)) + +(my-assert + (multiple-value-list (parse-integer " 123 " :junk-allowed t)) + (123 #+xcl 7 + #+(or clisp akcl allegro cmu sbcl ecls) 5 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown)) + +(my-assert + (multiple-value-list (parse-integer "123 t" :junk-allowed t)) + (123 #+xcl 4 + #+(or clisp akcl allegro cmu sbcl ecls) 3 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown)) + +(my-assert + (multiple-value-list (parse-integer " 123 t " :junk-allowed t)) + (123 #+xcl 8 + #+(or clisp akcl allegro cmu sbcl ecls) 5 + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown)) + +(my-assert + (multiple-value-list (parse-integer " ( 12 ) 43 t " :junk-allowed + t)) + (nil 1)) + +(my-assert + (setq a "q w e 1 2 r 4 d : :;;;") + "q w e 1 2 r 4 d : :;;;") + +(my-assert + (setq b "1 2 3 4 5 6 7") + "1 2 3 4 5 6 7") + +(my-assert + (setq c "1.3 4.223") + "1.3 4.223") + +(my-assert + (setq d "q w e r t z") + "q w e r t z") + +(my-assert + (multiple-value-list (parse-integer a)) + error) + +(my-assert + (multiple-value-list (parse-integer b)) + error) + +(my-assert + (multiple-value-list (parse-integer c)) + error) + +(my-assert + (multiple-value-list (parse-integer d)) + error) + +(my-assert + (multiple-value-list (parse-integer a :start 4 :end 6)) + error) + +(my-assert + (multiple-value-list (parse-integer b :start 2 :end 3)) + (2 3)) + +(my-assert + (multiple-value-list (parse-integer c :start 1)) + error) + +(my-assert + (multiple-value-list (parse-integer d :start 6)) + error) + +(my-assert + (multiple-value-list (parse-integer a :end 4)) + error) + +(my-assert + (multiple-value-list (parse-integer b :end 3)) + error) + +(my-assert + (multiple-value-list (parse-integer c :end 3)) + error) + +(my-assert + (multiple-value-list (parse-integer d :end 1)) + error) + +(my-assert + (multiple-value-list (parse-integer a :radix 1)) + error) + +(my-assert + (multiple-value-list (parse-integer b :radix 10)) + error) + +(my-assert + (multiple-value-list (parse-integer c :radix 20)) + error) + +(my-assert + (multiple-value-list (parse-integer d :radix 40)) + error) + +(my-assert + (multiple-value-list (parse-integer a :junk-allowed t)) + (nil 0)) + +(my-assert + (multiple-value-list (parse-integer b :junk-allowed t)) + (1 #+xcl 2 + #+(or clisp akcl allegro cmu sbcl ecls) 1 + #-(or xcl clisp akcl allegro cmu sbcl) unknown)) + +(my-assert + (multiple-value-list (parse-integer c :junk-allowed t)) + (1 1)) + +(my-assert + (multiple-value-list (parse-integer d :junk-allowed t)) + (nil 0)) + +(my-assert + (stream-element-type #+xcl stdin + #-xcl *terminal-io*) + character) + +(my-assert + (progn (setq a (make-string-input-stream "aaa bbb")) t) + t) + +(my-assert + (read a) + aaa) + +#+xcl +(my-assert + (b-clear-input a) + nil) + +(my-assert + (read a) + #+xcl error + #-xcl bbb) + +(my-assert + (progn (setq a (make-string-output-stream)) + (setq b (make-string-output-stream)) + (setq c (make-broadcast-stream a b)) t) + t) + +(my-assert + (print "xxx" c) + "xxx") + +(my-assert + (clear-output c) + nil) + +(my-assert + (finish-output c) + #+xcl t + #-xcl nil) + +(my-assert + (get-output-stream-string a) + " +\"xxx\" ") + +(my-assert + (get-output-stream-string b) + " +\"xxx\" ") + +(my-assert + (print "yyy" c) + "yyy") + +(my-assert + (clear-output c) + nil) + +(my-assert + (finish-output c) + #+xcl t + #-xcl nil) + +(my-assert + (print "zzz" a) + "zzz") + +(my-assert + (clear-output a) + nil) + +(my-assert + (finish-output a) + #+xcl t + #-xcl nil) + +(my-assert + (get-output-stream-string a) + #+xcl "" + #-xcl " +\"yyy\" +\"zzz\" ") + +(my-assert + (get-output-stream-string b) + " +\"yyy\" ") + +(my-assert + (progn (setq a (make-string-input-stream "123")) t) + t) + +(my-assert + (listen a) + t) + +(my-assert + (read a) + 123) + +(my-assert + (listen a) + nil) + +(my-assert + *print-case* + :upcase) + +(my-assert + *print-gensym* + t) + +(my-assert + *print-level* + nil) + +(my-assert + *print-length* + nil) + +(my-assert + *print-array* + t) + +(my-assert + *print-escape* + t) + +(my-assert + *print-pretty* + nil) + +(my-assert + *print-circle* + nil) + +(my-assert + *print-base* + 10) + +(my-assert + *print-radix* + nil) + +(my-assert + (setq string1 "Das ist ein Test mit Print ") + "Das ist ein Test mit Print ") + +(my-assert + (prin1-to-string string1) + "\"das ist ein test mit print \"") + +(my-assert + (princ-to-string string1) + "Das ist ein Test mit Print ") + +(my-assert + (progn (setq a (make-string-input-stream "123")) t) + t) + +(my-assert + (read-char-no-hang a) + #\1) + +(my-assert + (read a) + 23) + +(my-assert + (read-char-no-hang a) + error) + +(my-assert + (read-char-no-hang a nil "EOF") + "EOF") + +(my-assert + (progn (setq a (make-string-input-stream "1 2 ;32 abA")) + (setq b (make-string-input-stream " 1 2 3 A x y z +a b c")) t) + t) + +(my-assert + (read-delimited-list #\A b) + (1 2 3)) + +(my-assert + (setq c (multiple-value-list (read-line b))) + (" x y z" nil)) + +(my-assert + (length c) + 2) + +(my-assert + (multiple-value-list (read-line b)) + ("a b c" t)) + +(my-assert + (multiple-value-list (read-line b)) + error) + +(my-assert + (multiple-value-list (read-line b nil "EOF")) + ("EOF" t) + "read-line &optional input-stream eof-error-p eof-value recursive-p + +=> line, missing-newline-p +") + +(my-assert + (peek-char nil a) + #\1) + +(my-assert + (read-char a) + #\1) + +(my-assert + (peek-char t a) + #\2) + +(my-assert + (read-char a) + #\2) + +(my-assert + (peek-char t a) + #\;) + +(my-assert + (read-char a) + #\;) + +(my-assert + (peek-char #\A a) + #\A) + +(my-assert + (read-char a) + #\A) + +(my-assert + (peek-char nil a) + error) + +(my-assert + (peek-char nil a nil "EOF") + "EOF") + +(my-assert + (setq a (quote + ((berlin (dresden frankfurt bonn muenchen)) (mueller (karl luise dieter + aldo))))) + ((berlin (dresden frankfurt bonn muenchen)) (mueller (karl luise dieter + aldo)))) + +(my-assert + (progn (setq aa (make-string-input-stream "berlin d mueller :r")) t) + t) + +(my-assert + (defun ask (&optional (res nil)) + " (terpri)(terpri)(terpri) + (print '(*** Eingabe des Keywortes ***)) + (print '(- mit :r reset)) + (terpri)" (setq x (read aa)) " (print x)" (cond + ((equal x (quote :r)) (cons "--- reset ---" res)) + (t (cons (cadr (assoc x a)) (ask res))))) + ask) + +(my-assert + (ask) + ((dresden frankfurt bonn muenchen) nil (karl luise dieter aldo) "--- reset ---")) + +(my-assert + (setq string1 "Das ist ein Teststring") + "Das ist ein Teststring") + +(my-assert + (setq string2 "Auch das 1 2 3 ist ein Teststring") + "Auch das 1 2 3 ist ein Teststring") + +(my-assert + (multiple-value-list (read-from-string string1)) + (das 4)) + +(my-assert + (multiple-value-list (read-from-string string2)) + (auch 5)) + +(my-assert + (multiple-value-list (read-from-string string1 t nil :start 2)) + (s 4)) + +(my-assert + (multiple-value-list + (read-from-string string1 t nil :start 2 :preserve-whitespace t)) + (s 3)) + +(my-assert + (multiple-value-list (read-from-string string2 t nil :start 5)) + (das 9)) + +(my-assert + (multiple-value-list (read-from-string string2 t nil :start 5 :end + 6)) + (d 6)) + +(my-assert + (multiple-value-list (read-from-string string1 t nil :start 4 :end + 3)) + error) + +(my-assert + (multiple-value-list (read-from-string string1 t nil :end 0)) + error) + +(my-assert + (multiple-value-list (read-from-string string1 t nil :start -2 :end + 0)) + error) + +(my-assert + (multiple-value-list (read-from-string string1 t nil :end 2)) + (da 2)) + +(my-assert + *read-suppress* + nil) + +(my-assert + (standard-char-p (quote a)) + error) + +(my-assert + (standard-char-p (quote #\backspace)) + #+xcl t + #-xcl nil) + +(my-assert + (standard-char-p (quote #\tab)) + #+xcl t + #-xcl nil) + +(my-assert + (standard-char-p (quote #\newline)) + t) + +(my-assert + (standard-char-p (quote #\page)) + #+xcl t + #-xcl nil) + +(my-assert + (standard-char-p (quote #\return)) + #+xcl t + #-xcl nil) + +#-(or cmu sbcl sbcl) +(my-assert + (string-char-p (quote a)) + error) + +(my-assert + (characterp (quote + #\space)) + t) + +(my-assert + (characterp (quote + #\newline)) + t) + +(my-assert + (characterp (quote + #\backspace)) + t) + +(my-assert + (characterp (quote + #\a)) + t) + +(my-assert + (characterp (quote + #\8)) + t) + +(my-assert + (characterp (quote + #\-)) + t) + +(my-assert + (characterp (quote + #\n)) + t) + +(my-assert + (characterp (quote + #\()) + t) + +(my-assert + (stringp "das ist einer der Teststrings") + t) + +(my-assert + (stringp (quote (das ist natuerlich falsch))) + nil) + +(my-assert + (stringp "das ist die eine Haelfte" "und das die andere") + error) + +(my-assert + (setq j 0) + 0) + +(my-assert + (with-input-from-string (s "animal crackers" :start 6) (read s)) + crackers) + +(my-assert + (with-input-from-string (s "animal crackers" :index j :start 6) (read s)) + crackers) + +(my-assert + j + 15) + +(my-assert + (with-input-from-string (s "animal crackers" :index j :start 7) (read s)) + crackers) + +(my-assert + j + 15) + +(my-assert + (with-input-from-string (s "animal crackers" :index j :start 2) (read s)) + imal) + +(my-assert + j + 7) + +(my-assert + (with-input-from-string (s "animal crackers" :index j :start 0 :end 6) (read s)) + animal) + +(my-assert + j + 6) + +(my-assert + (with-input-from-string (s "animal crackers" + :index j + :start 0 :end 12) + (read s)) + animal) + +(my-assert + j + 7) + +(my-assert + (with-input-from-string (s "animal crackers" :index j :start -1) (read s)) + error) + +(my-assert + j + 7) + +(my-assert + (with-input-from-string (s "animal crackers" + :index j + :start 6 :end 20) + (read s)) + #+xcl + crackers + #+(or clisp akcl allegro sbcl cmu ecls) + error + #-(or xcl clisp akcl allegro sbcl cmu ecls) + unknown) + +(my-assert + j + #+xcl + 20 + #+(or clisp akcl allegro sbcl cmu ecls) + 7 + #-(or xcl clisp akcl allegro sbcl cmu ecls) + unknown) + +(my-assert + (setq a "Das ist wieder einmal einer der SUUPERTESTstrings.") + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (progn (setq b (make-string-output-stream)) t) + t) + +(my-assert + (write-string a b) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (write-string a b :start 10) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (write-string a b :start 80) + #+xcl "Das ist wieder einmal einer der SUUPERTESTstrings." + #-xcl error) + +(my-assert + (write-string a b :end 5) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (write-string a b :end -2) + error) + +(my-assert + (write-string a b :end 100) + #+(or sbcl cmu xcl) + "Das ist wieder einmal einer der SUUPERTESTstrings." + #-(or sbcl cmu xcl) + error) + +(my-assert + (write-string a b :start 5 :end 20) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (write-string a b :start 10 :end 5) + #+xcl "Das ist wieder einmal einer der SUUPERTESTstrings." + #-xcl error) + +(my-assert + (get-output-stream-string b) + #+(or sbcl cmu xcl) + "Das ist wieder einmal einer der SUUPERTESTstrings.eder einmal einer der SUUPERTESTstrings.Das iDas ist wieder einmal einer der SUUPERTESTstrings.st wieder einma" + #+(or clisp akcl ecls) + "Das ist wieder einmal einer der SUUPERTESTstrings.eder einmal einer der SUUPERTESTstrings.Das ist wieder einma" + #-(or xcl clisp akcl sbcl cmu ecls) + unknown) + +(my-assert + (write-string a b) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (length (get-output-stream-string b)) + 50) + +(my-assert + (write-line a b) + "Das ist wieder einmal einer der SUUPERTESTstrings.") + +(my-assert + (length (get-output-stream-string b)) + 51) + +(my-assert + (with-output-to-string (s) (print (quote xxx) s)) + " +XXX ") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + a) + "") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s))) + 123) + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + a) + "123") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s))) + 4567) + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s)) + a) + "1234567") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s)) + (with-output-to-string (s a) + (princ 890 s))) + 890) + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s)) + (with-output-to-string (s a) + (princ 890 s)) + a) + "1234567890") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s)) + (with-output-to-string (s a) + (princ 890 s)) + (with-output-to-string (s a) + (princ (quote a) s))) + error + "All 10 characters are up. This should fail") + +(my-assert + (let ((a (make-array 10 + :element-type 'character + :fill-pointer 0))) + (with-output-to-string (s a) (princ 123 s)) + (with-output-to-string (s a) (princ 4567 s)) + (with-output-to-string (s a) + (princ 890 s)) + (ignore-errors + (with-output-to-string (s a) + (princ (quote a) s))) + a) + "1234567890") + +(my-assert + (setq a + (make-array 10 :element-type 'character + :fill-pointer 0 + :adjustable t)) + "") + +(my-assert + (with-output-to-string (s a) (princ 123 s)) + 123) + +(my-assert + a + "123") + +(my-assert + (with-output-to-string (s a) (princ 4567 s)) + 4567) + +(my-assert + a + "1234567") + +(my-assert + (with-output-to-string (s a) (princ 890 s)) + 890) + +(my-assert + a + "1234567890") + +(my-assert + (with-output-to-string (s a) (princ (quote abcde) s)) + abcde) + +(my-assert + a + "1234567890ABCDE") + +(my-assert + (with-output-to-string (s a) (princ (quote fghi) s)) + fghi) + +(my-assert + a + "1234567890ABCDEFGHI") + +(makunbound 'bs) +(makunbound 'a) +(makunbound 'b) +(makunbound 'c) +(makunbound 'd) +(makunbound 'aa) +(makunbound 'string1) +(makunbound 'string2) +(makunbound 'x) +(makunbound 'j) +(makunbound 's1) +(makunbound 'str1) + diff --git a/src/ansi-tests/lambda.lisp b/src/ansi-tests/lambda.lisp new file mode 100644 index 000000000..d25f83a85 --- /dev/null +++ b/src/ansi-tests/lambda.lisp @@ -0,0 +1,279 @@ +;;; based on 1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (makunbound 'b) b) + +(my-assert + (makunbound 'e) e) + +(my-assert + (setq z 2) 2) + +(my-assert + ((lambda (z) (declare (special z)) (list z (symbol-value 'z))) 3) + (3 3)) + +(my-assert + (makunbound 'z) z) + +(my-assert + ((lambda (a b) (+ a (* b 3))) 4 5) + 19) + +(my-assert + ((lambda (a &optional (b 2)) (+ a (* b 3))) 4 5) + 19) + +(my-assert + ((lambda (a &optional (b 2)) (+ a (* b 3))) 4) + 10) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))) + (2 nil 3 nil nil)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6) + (6 t 3 nil nil)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6 3) + (6 t 3 t nil)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6 3 + 8) + (6 t 3 t (8))) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6 3 + 8 9 10 11) + (6 t 3 t (8 9 10 11))) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2) + (1 2 nil nil)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6) + (1 2 6 nil)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8) + (1 2 nil 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6 :d 8) + (1 2 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8 :c 6) + (1 2 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) :a 1 :d 8 :c 6) + (:a 1 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) :a :b :c :d) + (:a :b :d nil)) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + 1) + (1 3 nil 1 nil)) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + 1 2) + (1 2 nil 1 nil)) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + :c 7) + (:c 7 nil :c nil)) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + 1 6 :c 7) + (1 6 7 1 (:c 7))) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + 1 6 :d 8) + (1 6 nil 8 (:d 8))) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) + 1 6 :d 8 :c + 9 :d 10) + (1 6 9 8 (:d 8 :c 9 :d 10))) + +(my-assert + ((lambda (x &aux (a 3) (b 4)) (+ x (* a b))) 2) + 14) + +(my-assert + ((lambda (x y &optional a b &rest z &key c (d y) &aux (u 3) (v 4)) + (+ x y a (* b (car z)) c (* d u) v)) + 3 4 5 2 7 :c 6 :d 8) + program-error) + +(my-assert + ((lambda (x y &optional a b &rest z &key c (d y) &aux (u 3) (v 4)) + (+ x y a (* b (car z)) c (* d u) v)) + 3 4 5 2 7 :c 6) + program-error) + +(my-assert + ((lambda (x &aux c) (cons x c)) (quote a)) + (a)) + +(my-assert + ((lambda (x &rest y z) (list x y z)) 1 2 3) + error) + +(my-assert + ((lambda (5 a b) (list a b)) 1 2) + error) + +(my-assert + ((lambda ((length (quote (a b))) c) (list c)) 1) + error) + +(my-assert + ((lamda (x &key :y :z) (list x y z)) 1 :y 2 :z 3) + error) + +(my-assert + ((lambda (x y) (list x y z)) 1 2) + unbound-variable) + +(my-assert + ((lambda (x y) (list x y z)) 1 2 3) + error) + +(my-assert + ((lambda (&optional) (list a b c)) 1) + error) + +(my-assert + ((lambda (&optional (a)) (list a)) 1) + (1)) + +(my-assert + ((lambda (&optional (a b)) (list a b)) 1) + unbound-variable) + +(my-assert + ((lambda (&optional (a 3 b)) (list a b)) 1) + (1 t)) + +(my-assert + ((lambda (&optional (a 3)) (list a)) 1) + (1)) + +(my-assert + ((lambda (&optional (a 3 b 4)) (list a b)) 1) + #+xcl (1 t) + #-xcl error) + +(my-assert + ((lambda (x) (list x y)) 1 2) + error) + +(my-assert + ((lambda (x) (list x)) 1 2) + error) + +(my-assert + ((lambda (#\a) (list a)) 1) + error) + +(my-assert + ((lambda (#*10) (list 1 2 3))) + error) + +(my-assert + ((lambda (x y) ((lambda (a b) (list a b)) (quote u) (quote v))) 5 6) + (u v)) + +(my-assert + ((lambda (x y) (list x y)) 1) + error) + +(my-assert + ((lambda (x &rest y &optional (z 5)) (list x y z)) 1 3) + error) + +(my-assert + ((lambda (x &x) (list x)) 7) + error) + +(my-assert + ((lambda (x &aux) (list x)) 6) + (6)) + +(my-assert + ((lambda (x &aux y) (list x y)) 6) + (6 nil)) + +(my-assert + ((lambda (x &aux (y)) (list x y)) 6) + (6 nil)) + +(my-assert + ((lambda (x &rest) (list x)) 2) + error) + +(my-assert + ((lambda (x &key) (list x)) 3) + (3)) + +(my-assert + ((lambda (x &key y) (list x)) 3) + (3)) + +(my-assert + ((lambda (x &key y) (list x)) 3 :y) + error) + +(my-assert + ((lambda (x &key y) (list x)) :\3) + (:\3)) + +(my-assert + ((lambda nil (list 1 2 3))) + (1 2 3)) + +(my-assert + ((lambda nil (list 1 2 3)) 4 5) + error) + +(my-assert + ((lambda (list 1 2 3))) + error) + +(my-assert + ((lambda (x))) + error) + +(my-assert + ((lambda (&aux &key &rest &optional))) + error) + +(my-assert + ((lambda (a b &key c d &allow-other-keys) (list a b c d e f)) 1 2 :c + 6 :d 8 :e 5 + :f 7) + error) + +(my-assert + ((lambda (x &allow-other-keys) (list x y)) 2 :y 3) + error) + +(my-assert + ((lambda)) + error) + diff --git a/src/ansi-tests/lists151.lisp b/src/ansi-tests/lists151.lisp new file mode 100644 index 000000000..0cafc7309 --- /dev/null +++ b/src/ansi-tests/lists151.lisp @@ -0,0 +1,837 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (makunbound 'a) + a) + +(my-assert + (makunbound 'x) + x) + +(my-assert + (car '(a b c d e f g)) + a) + +(my-assert + (cdr '(a b c d e f g)) + (b c d e f g)) + +(my-assert + (caar '((a) b c d e f g)) + a) + +(my-assert + (cadr '(a b c d e f g)) + b) + +(my-assert + (cdar '((a b) c d e f g)) + (b)) + +(my-assert + (cddr '(a b c d e f g)) + (c d e f g)) + +(my-assert + (caaar '(((a)) b c d e f g)) + a) + +(my-assert + (caadr '(a (b) c d e f g)) + b) + +(my-assert + (cadar '((a b) c d e f g)) + b) + +(my-assert + (caddr '(a b c d e f g)) + c) + +(my-assert + (cdaar '(((a b)) c d e f g)) + (b)) + +(my-assert + (cdadr '(a (b c) d e f g)) + (c)) + +(my-assert + (cddar '((a b c) d e f g)) + (c)) + +(my-assert + (cdddr '(a b c d e f g)) + (d e f g)) + +(my-assert + (caaaar '((((a))) b c d e f g)) + a) + +(my-assert + (caaadr '(a ((b)) c d e f g)) + b) + +(my-assert + (caadar '((a (b)) c d e f g)) + b) + +(my-assert + (caaddr '(a b (c) d e f g)) + c) + +(my-assert + (cadaar '(((a b)) c d e f g)) + b) + +(my-assert + (cadadr '(a (b c) d e f g)) + c) + +(my-assert + (caddar '((a b c) d e f g)) + c) + +(my-assert + (cadddr '(a b c d e f g)) + d) + +(my-assert + (cdaaar '((((a b))) c d e f g)) + (b)) + +(my-assert + (cdaadr '(a ((b c)) d e f g)) + (c)) + +(my-assert + (cdadar '((a (b c)) d e f g)) + (c)) + +(my-assert + (cdaddr '(a b (c d) e f g)) + (d)) + +(my-assert + (cddaar '(((a b c)) d e f g)) + (c)) + +(my-assert + (cddadr '(a (b c d) e f g)) + (d)) + +(my-assert + (cdddar '((a b c d) e f g)) + (d)) + +(my-assert + (cddddr '(a b c d e f g)) + (e f g)) + +(my-assert + (car '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((((1 2 3) 4) 5) (6 7))) + +(my-assert + (cdr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((((u v w) x) y) ((q w e) r) (a b c) e f g)) + +(my-assert + (caar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (((1 2 3) 4) 5)) + +(my-assert + (cadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (((u v w) x) y)) + +(my-assert + (cdar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((6 7))) + +(my-assert + (cddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (((q w e) r) (a b c) e f g)) + +(my-assert + (caaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((1 2 3) 4)) + +(my-assert + (caadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((u v w) x)) + +(my-assert + (cadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (6 7)) + +(my-assert + (caddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((q w e) r)) + +(my-assert + (cdaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (5)) + +(my-assert + (cdadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + (y)) + +(my-assert + (cddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + nil) + +(my-assert + (cdddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b c) + e f g)) + ((a b c) e f g)) + +(my-assert + (caaaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (1 2 3)) + +(my-assert + (caaadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (u v w)) + +(my-assert + (caadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + 6) + +(my-assert + (caaddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (q w e)) + +(my-assert + (cadaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + 5) + +(my-assert + (cadadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + y) + +(my-assert + (caddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + nil) + +(my-assert + (cadddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (a b c)) + +(my-assert + (cdaaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (4)) + +(my-assert + (cdaadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (x)) + +(my-assert + (cdadar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (7)) + +(my-assert + (cdaddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (r)) + +(my-assert + (cddaar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + nil) + +(my-assert + (cddadr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + nil) + +(my-assert + (cdddar '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + nil) + +(my-assert + (cddddr '(((((1 2 3) 4) 5) (6 7)) (((u v w) x) y) ((q w e) r) (a b + c) e f g)) + (e f g)) + +(my-assert + (car 'nil) + nil) + +(my-assert + (cdr 'nil) + nil) + +(my-assert + (caar 'nil) + nil) + +(my-assert + (cadr 'nil) + nil) + +(my-assert + (cdar 'nil) + nil) + +(my-assert + (cddr 'nil) + nil) + +(my-assert + (caaar 'nil) + nil) + +(my-assert + (caadr 'nil) + nil) + +(my-assert + (cadar 'nil) + nil) + +(my-assert + (caddr 'nil) + nil) + +(my-assert + (cdaar 'nil) + nil) + +(my-assert + (cdadr 'nil) + nil) + +(my-assert + (cddar 'nil) + nil) + +(my-assert + (cdddr 'nil) + nil) + +(my-assert + (caaaar 'nil) + nil) + +(my-assert + (caaadr 'nil) + nil) + +(my-assert + (caadar 'nil) + nil) + +(my-assert + (caaddr 'nil) + nil) + +(my-assert + (cadaar 'nil) + nil) + +(my-assert + (cadadr 'nil) + nil) + +(my-assert + (caddar 'nil) + nil) + +(my-assert + (cadddr 'nil) + nil) + +(my-assert + (cdaaar 'nil) + nil) + +(my-assert + (cdaadr 'nil) + nil) + +(my-assert + (cdadar 'nil) + nil) + +(my-assert + (cdaddr 'nil) + nil) + +(my-assert + (cddaar 'nil) + nil) + +(my-assert + (cddadr 'nil) + nil) + +(my-assert + (cdddar 'nil) + nil) + +(my-assert + (cddddr 'nil) + nil) + +(my-assert + (car '(a b c d e f g)) + a) + +(my-assert + (cdr '(a b c d e f g)) + (b c d e f g)) + +(my-assert + (caar '(a b c d e f g)) + type-error) + +(my-assert + (cadr '(a b c d e f g)) + b) + +(my-assert + (cdar '(a b c d e f g)) + type-error) + +(my-assert + (cddr '(a b c d e f g)) + (c d e f g)) + +(my-assert + (caaar '(a b c d e f g)) + type-error) + +(my-assert + (caadr '(a b c d e f g)) + type-error) + +(my-assert + (cadar '(a b c d e f g)) + type-error) + +(my-assert + (caddr '(a b c d e f g)) + c) + +(my-assert + (cdaar '(a b c d e f g)) + type-error) + +(my-assert + (cdadr '(a b c d e f g)) + type-error) + +(my-assert + (cddar '(a b c d e f g)) + type-error) + +(my-assert + (cdddr '(a b c d e f g)) + (d e f g)) + +(my-assert + (caaaar '(a b c d e f g)) + type-error) + +(my-assert + (caaadr '(a b c d e f g)) + type-error) + +(my-assert + (caadar '(a b c d e f g)) + type-error) + +(my-assert + (caaddr '(a b c d e f g)) + type-error) + +(my-assert + (cadaar '(a b c d e f g)) + type-error) + +(my-assert + (cadadr '(a b c d e f g)) + type-error) + +(my-assert + (caddar '(a b c d e f g)) + type-error) + +(my-assert + (cadddr '(a b c d e f g)) + d) + +(my-assert + (cdaaar '(a b c d e f g)) + type-error) + +(my-assert + (cdaadr '(a b c d e f g)) + type-error) + +(my-assert + (cdadar '(a b c d e f g)) + type-error) + +(my-assert + (cdaddr '(a b c d e f g)) + type-error) + +(my-assert + (cddaar '(a b c d e f g)) + type-error) + +(my-assert + (cddadr '(a b c d e f g)) + type-error) + +(my-assert + (cdddar '(a b c d e f g)) + type-error) + +(my-assert + (cddddr '(a b c d e f g)) + (e f g)) + +(my-assert + (car '(a)) + a) + +(my-assert + (cdr '(a)) + nil) + +(my-assert + (caar '(a)) + type-error) + +(my-assert + (cadr '(a)) + nil) + +(my-assert + (cdar '(a)) + type-error) + +(my-assert + (cddr '(a)) + nil) + +(my-assert + (caaar '(a)) + type-error) + +(my-assert + (caadr '(a)) + nil) + +(my-assert + (cadar '(a)) + type-error) + +(my-assert + (caddr '(a)) + nil) + +(my-assert + (cdaar '(a)) + type-error) + +(my-assert + (cdadr '(a)) + nil) + +(my-assert + (cddar '(a)) + type-error) + +(my-assert + (cdddr '(a)) + nil) + +(my-assert + (caaaar '(a)) + type-error) + +(my-assert + (caaadr '(a)) + nil) + +(my-assert + (caadar '(a)) + type-error) + +(my-assert + (caaddr '(a)) + nil) + +(my-assert + (cadaar '(a)) + type-error) + +(my-assert + (cadadr '(a)) + nil) + +(my-assert + (caddar '(a)) + type-error) + +(my-assert + (cadddr '(a)) + nil) + +(my-assert + (cdaaar '(a)) + type-error) + +(my-assert + (cdaadr '(a)) + nil) + +(my-assert + (cdadar '(a)) + type-error) + +(my-assert + (cdaddr '(a)) + nil) + +(my-assert + (cddaar '(a)) + type-error) + +(my-assert + (cddadr '(a)) + nil) + +(my-assert + (cdddar '(a)) + type-error) + +(my-assert + (cddddr '(a)) + nil) + +(my-assert + (cons 1 2) + (1 . 2)) + +(my-assert + (cons 'a 'b) + (a . b)) + +(my-assert + (cons 'a 'b 'c) + program-error) + +(my-assert + (cons 'a) + program-error) + +(my-assert + (cons) + program-error) + +(my-assert + (cons 'a 'nil) + (a)) + +(my-assert + (cons 'nil 'a) + (nil . a)) + +(my-assert + (cons 'a (cons 'b (cons 'c 'nil))) + (a b c)) + +(my-assert + (cons 'a '(b c d)) + (a b c d)) + +(my-assert + (tree-equal 1 1) + t) + +(my-assert + (tree-equal 'word 'word) + t) + +(my-assert + (tree-equal 'word1 'word2) + nil) + +(my-assert + (tree-equal '(a b) '(a b)) + t) + +(my-assert + (tree-equal '(a (b c)) '((a b) c)) + nil) + +(my-assert + (tree-equal 5 (+ 2 3)) + t) + +(my-assert + (tree-equal '(a (b quote nil)) '(a (b))) + nil) + +(my-assert + (tree-equal '(a (b . 1.0)) '(a (b #c(1.0 0.0)))) + nil) + +(my-assert + (tree-equal 1 1 :test #'eq) + t) + +(my-assert + (tree-equal 'word 'word :test #'eq) + t) + +(my-assert + (tree-equal 'word1 'word2 :test #'eq) + nil) + +(my-assert + (tree-equal '(a b) '(a b) :test #'eq) + t) + +(my-assert + (tree-equal '(a (b c)) '((a b) c) :test #'eq) + nil) + +(my-assert + (tree-equal 5 (+ 2 3) :test #'eq) + t) + +(my-assert + (tree-equal '(a (b)) '(a (b)) :test #'eq) + t) + +(my-assert + (tree-equal '(a (b . 1.0)) '(a (b #c(1.0 0.0))) :test #'eq) + nil) + +(my-assert + (tree-equal 1 1 :test #'eql) + t) + +(my-assert + (tree-equal 'word 'word :test #'eql) + t) + +(my-assert + (tree-equal 'word1 'word2 :test #'eql) + nil) + +(my-assert + (tree-equal '(a b) '(a b) :test #'eql) + t) + +(my-assert + (tree-equal '(a (b c)) '((a b) c) :test #'eql) + nil) + +(my-assert + (tree-equal 5 (+ 2 3) :test #'eql) + t) + +(my-assert + (tree-equal '(a (b)) '(a (b)) :test #'eql) + t) + +(my-assert + (tree-equal '(a (b . 1.0)) '(a (b #c(1.0 0.0))) :test #'eql) + nil) + +(my-assert + (tree-equal 1 1 :test #'equal) + t) + +(my-assert + (tree-equal 'word 'word :test #'equal) + t) + +(my-assert + (tree-equal 'word1 'word2 :test #'equal) + nil) + +(my-assert + (tree-equal '(a b) '(a b) :test #'equal) + t) + +(my-assert + (tree-equal '(a (b c)) '((a b) c) :test #'equal) + nil) + +(my-assert + (tree-equal 5 (+ 2 3) :test #'equal) + t) + +(my-assert + (tree-equal '(a (b)) '(a (b)) :test #'equal) + t) + +(my-assert + (tree-equal '(a (b . 1.0)) '(a (b #c(1.0 0.0))) :test #'equal) + nil) + +(my-assert + (tree-equal 1 1 :test-not #'eq) + nil) + +(my-assert + (tree-equal 'word 'word :test-not #'eq) + nil) + +(my-assert + (tree-equal 'word1 'word2 :test-not #'eq) + t) + +(my-assert + (tree-equal '(a b) '(a b) :test-not #'eq) + nil) + +(my-assert + (tree-equal '(a (b c)) '((a b) c) :test-not #'eq) + nil) + +(my-assert + (tree-equal 5 (+ 2 3) :test-not #'eq) + nil) + +(my-assert + (tree-equal '(a (b)) '(a (b)) :test-not #'eq) + nil) + +(my-assert + (tree-equal '(a (b . 1.0)) '(a (b #c(1.0 0.0))) :test-not #'eq) + nil) + diff --git a/src/ansi-tests/lists152.lisp b/src/ansi-tests/lists152.lisp new file mode 100644 index 000000000..f7a1cb7e3 --- /dev/null +++ b/src/ansi-tests/lists152.lisp @@ -0,0 +1,1056 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (endp 'nil) + t) + +(my-assert + (endp (cons 'a 'b)) + nil) + +(my-assert + (endp (append (list 'a 'b) 'c)) + nil) + +(my-assert + (endp (list 'a 'b 'c)) + nil) + +(my-assert + (endp (list 'a 'b 'c 'd)) + nil) + +(my-assert + (endp (append (list 'a 'b 'c) 'd)) + nil) + +(my-assert + (endp (list ''nil ''nil)) + nil) + +(my-assert + (list-length 'nil) + 0) + +(my-assert + (list-length (cons 'a 'b)) + #+xcl 1 + #-xcl type-error) + +(my-assert + (list-length (list 'a 'b 'c 'd)) + 4) + +(my-assert + (list-length + (list 'a (list 'b 'c) 'd)) + 3) + +(my-assert + (let ((x (list 'a 'b 'c))) + (rplacd (last x) + x) + (list-length x)) + nil) + +(my-assert + (nth 0 + (list 'a 'b 'c 'd)) + a) + +(my-assert + (nth 1 + (list 'a 'b 'c 'd)) + b) + +(my-assert + (nth 3 + (list 'a 'b 'c 'd)) + d) + +(my-assert + (nth 5 + (list 'a 'b 'c 'd)) + nil) + +(my-assert + (nth -2 + (list 'a 'b 'c 'd)) + type-error) + +(my-assert + (nth 0 'nil) + nil) + +(my-assert + (nth 2 'nil) + nil) + +(my-assert + (first (list 1 2 3 4 5 6 7 8 9 10 11)) + 1) + +(my-assert + (second (list 1 2 3 4 5 6 7 8 9 10 11)) + 2) + +(my-assert + (third (list 1 2 3 4 5 6 7 8 9 10 11)) + 3) + +(my-assert + (fourth (list 1 2 3 4 5 6 7 8 9 10 11)) + 4) + +(my-assert + (fifth (list 1 2 3 4 5 6 7 8 9 10 11)) + 5) + +(my-assert + (sixth (list 1 2 3 4 5 6 7 8 9 10 11)) + 6) + +(my-assert + (seventh (list 1 2 3 4 5 6 7 8 9 10 11)) + 7) + +(my-assert + (eighth (list 1 2 3 4 5 6 7 8 9 10 11)) + 8) + +(my-assert + (ninth (list 1 2 3 4 5 6 7 8 9 10 11)) + 9) + +(my-assert + (tenth (list 1 2 3 4 5 6 7 8 9 10 11)) + 10) + +(my-assert + (first (list 1 2 3)) + 1) + +(my-assert + (second (list 1 2 3)) + 2) + +(my-assert + (third (list 1 2 3)) + 3) + +(my-assert + (fourth (list 1 2 3)) + nil) + +(my-assert + (fifth (list 1 2 3)) + nil) + +(my-assert + (sixth (list 1 2 3)) + nil) + +(my-assert + (seventh (list 1 2 3)) + nil) + +(my-assert + (eighth (list 1 2 3)) + nil) + +(my-assert + (ninth (list 1 2 3)) + nil) + +(my-assert + (tenth (list 1 2 3)) + nil) + +(my-assert + (first 'nil) + nil) + +(my-assert + (second 'nil) + nil) + +(my-assert + (third 'nil) + nil) + +(my-assert + (fourth 'nil) + nil) + +(my-assert + (fifth 'nil) + nil) + +(my-assert + (sixth 'nil) + nil) + +(my-assert + (seventh 'nil) + nil) + +(my-assert + (eighth 'nil) + nil) + +(my-assert + (ninth 'nil) + nil) + +(my-assert + (tenth 'nil) + nil) + +(my-assert + (rest (list 1 2 3 4 5)) + (2 3 4 5)) + +(my-assert + (rest 'nil) + nil) + +(my-assert + (rest (cons 'a 'b)) + b) + +(my-assert + (rest (append (list 1 2 3) 4)) + (2 3 . 4)) + +(my-assert + (nthcdr 0 + (list 'a 'b 'c 'd)) + (a b c d)) + +(my-assert + (nthcdr 1 + (list 'a 'b 'c 'd)) + (b c d)) + +(my-assert + (nthcdr 3 + (list 'a 'b 'c 'd)) + (d)) + +(my-assert + (nthcdr 5 + (list 'a 'b 'c 'd)) + nil) + +(my-assert + (nthcdr -2 + (list 'a 'b 'c 'd)) + type-error) + +(my-assert + (nthcdr 0 'nil) + nil) + +(my-assert + (nthcdr 2 'nil) + nil) + +(my-assert + (last (list 1 2 3 4 5)) + (5)) + +(my-assert + (last 'nil) + nil) + +(my-assert + (last (cons 'a 'b)) + (a . b)) + +(my-assert + (last (append (list 1 2 3) 4)) + (3 . 4)) + +(my-assert + (list 'a 'b 'c 'd) + (a b c d)) + +(my-assert + (list 'a) + (a)) + +(my-assert + (list (list 'a 'b) + (list 'c 'd)) + ((a b) + (c d))) + +(my-assert + (list 'a 'nil) + (a nil)) + +(my-assert + (list 'nil 'a) + (nil a)) + +(my-assert + (list 'nil 'nil) + (nil nil)) + +(my-assert + (list) + nil) + +(my-assert + (list 3 4 'a + (car (cons 'b 'c)) + (+ 6 -2)) + (3 4 a b 4)) + +(my-assert + (list* 'a 'b 'c 'd) + (a b c . d)) + +(my-assert + (list* 'a) + a) + +(my-assert + (list* (list 'a 'b) + (list 'c 'd)) + ((a b) + c d)) + +(my-assert + (list* 'a 'nil) + (a)) + +(my-assert + (list* 'nil 'a) + (nil . a)) + +(my-assert + (list* 'nil 'nil) + (nil)) + +(my-assert + (list*) + program-error) + +(my-assert + (list* 3 4 'a + (car (cons 'b 'c)) + (+ 6 -2)) + (3 4 a b . 4)) + +(my-assert + (list* 'a 'b 'c + (list 'd 'e 'f)) + (a b c d e f)) + +(my-assert + (list* x) + unbound-variable) + +(my-assert + (list* 'nil) + nil) + +(my-assert + (make-list 5) + (nil nil nil nil nil)) + +(my-assert + (make-list 5 :initial-element) + program-error) + +(my-assert + (make-list 3 :initial-element 'rah) + (rah rah rah)) + +(my-assert + (make-list 0) + nil) + +(my-assert + (make-list 0 :initial-element 'aaa) + nil) + +(my-assert + (make-list 5 :initial-element 'nil) + (nil nil nil nil nil)) + +(my-assert + (make-list) + program-error) + +(my-assert + (append (list 'a 'b 'c) + (list 'd 'e 'f) + 'nil + (list 'g)) + (a b c d e f g)) + +(my-assert + (append (list 'a 'b 'c) + 'd) + (a b c . d)) + +(my-assert + (append 'a 'b) + error) + +(my-assert + (append 'a 'nil) + error) + +(my-assert + (append 'nil 'nil) + nil) + +(my-assert + (append 'nil 'a) + #+xcl error + #-xcl a) + +(my-assert + (append 'nil + (list 'a 'b 'c)) + (a b c)) + +(my-assert + (setq x + (list 'a 'b 'c)) + (a b c)) + +(my-assert + (setq y + (list 'd 'e 'f)) + (d e f)) + +(my-assert + (setq r + (append x y)) + (a b c d e f)) + +(my-assert + x + (a b c)) + +(my-assert + y + (d e f)) + +(my-assert + (eq (cdddr r) + y) + t) + +(my-assert + (copy-list (list 1 2 3 4 5)) + (1 2 3 4 5)) + +(my-assert + (copy-list 'nil) + nil) + +(my-assert + (copy-list (cons 'a 'b)) + (a . b)) + +(my-assert + (copy-list (append (list 1 2 3) 4)) + (1 2 3 . 4)) + +(my-assert + (setq l + (list 1 2 3 4 5)) + (1 2 3 4 5)) + +(my-assert + (eq l + (copy-list l)) + nil) + +(my-assert + (eql l + (copy-list l)) + nil) + +(my-assert + (equal l + (copy-list l)) + t) + +(my-assert + (equalp l + (copy-list l)) + t) + +(my-assert + (copy-alist 'a) + #-clisp error + #+clisp a) + +(my-assert + (copy-alist 'nil) + nil) + +(my-assert + (copy-alist 5) + #-clisp error + #+clisp 5) + +(my-assert + (copy-alist (list 'a 'b)) + #+(or xcl clisp allegro cmu sbcl) (a b) + #+(or ecls gcl) error + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (copy-alist (list (cons 1 'a) + (cons 2 'b) + (cons 3 'c))) + ((1 . a) + (2 . b) + (3 . c))) + +(my-assert + (setq x + (list (cons 1 'a) + (cons 2 'b) + (cons 3 'c))) + ((1 . a) + (2 . b) + (3 . c))) + +(my-assert + (eq x + (copy-alist x)) + nil) + +(my-assert + (eql x + (copy-alist x)) + nil) + +(my-assert + (equal x + (copy-alist x)) + t) + +(my-assert + (eq (cadr x) + (cadr (copy-alist x))) + nil) + +(my-assert + (eql (cadr x) + (cadr (copy-alist x))) + nil) + +(my-assert + (equal (cadr x) + (cadr (copy-alist x))) + t) + +(my-assert + (copy-alist (list (cons 1 2)) + (list (cons a b))) + error) + +(my-assert + (copy-alist (list (list 'a 'b) + 'c + (list 'd 'e))) + #+(or xcl clisp allegro cmu sbcl) ((a b) c (d e)) + #+(or gcl ecls) error + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (copy-tree 'x) + x) + +(my-assert + (copy-tree 5) + 5) + +(my-assert + (copy-tree (list 'a 'b)) + (a b)) + +(my-assert + (copy-tree (list 'a 'b + (list 'c + (list 'd) + (list 'e 'f)) + 'g)) + (a b + (c (d) + (e f)) + g)) + +(my-assert + (copy-tree (list (cons 1 'e) + (cons 2 'f))) + ((1 . e) + (2 . f))) + +(my-assert + (copy-tree #*001) + #*001) + +(my-assert + (setq x + (list 'a 'b + (list 'c 'd) + 'e)) + (a b + (c d) + e)) + +(my-assert + (eq x + (copy-tree x)) + nil) + +(my-assert + (eql x + (copy-tree x)) + nil) + +(my-assert + (equal x + (copy-tree x)) + t) + +(my-assert + (eq (cdaddr x) + (cdaddr (copy-tree x))) + nil) + +(my-assert + (eql (cdaddr x) + (cdaddr (copy-tree x))) + nil) + +(my-assert + (equal (cdaddr x) + (cdaddr (copy-tree x))) + t) + +(my-assert + (revappend (list 'a 'b 'c) + (list 'd 'e 'f) + 'nil + (list 'g)) + program-error) + +(my-assert + (revappend (list 'a 'b 'c) + 'd) + (c b a . d)) + +(my-assert + (revappend 'a 'b) + #-clisp type-error + #+clisp b) + +(my-assert + (revappend 'a 'nil) + #-clisp type-error + #+clisp nil) + +(my-assert + (revappend 'nil 'nil) + nil) + +(my-assert + (revappend 'nil 'a) + a) + +(my-assert + (revappend 'nil + (list 'a 'b 'c)) + (a b c)) + +(my-assert + (revappend (list 'a 'b 'c) + (list 'd 'e 'f)) + (c b a d e f)) + +(my-assert + (revappend (list 'd 'e 'f) + (list 'a 'b 'c)) + (f e d a b c)) + +(my-assert + (eql (revappend (list 'a 'b 'c) + (list 'd 'e 'f)) + (append (reverse (list 'a 'b 'c)) + (list 'd 'e 'f))) + nil) + +(my-assert + (equal (revappend (list 'a 'b 'c) + (list 'd 'e 'f)) + (append (reverse (list 'a 'b 'c)) + (list 'd 'e 'f))) + t) + +(my-assert + (setq x + (list 'a 'b 'c)) + (a b c)) + +(my-assert + (setq y + (list 'd 'e 'f)) + (d e f)) + +(my-assert + (setq r + (revappend x y)) + (c b a d e f)) + +(my-assert + x + (a b c)) + +(my-assert + y + (d e f)) + +(my-assert + (eq (cdddr r) + y) + t) + +(my-assert + (setq x + (list 'a 'b 'c) + y + (list 'd 'e 'f)) + (d e f)) + +(my-assert + (nconc x y) + (a b c d e f)) + +(my-assert + x + (a b c d e f)) + +(my-assert + (eq (cdddr x) + y) + t) + +(my-assert + (setq x + (list 'a 'b 'c) + y + (list 'd 'e 'f) + z + (list 'g 'h 'i)) + (g h i)) + +(my-assert + (nconc) + nil) + +(my-assert + (nconc x) + (a b c)) + +(my-assert + (nconc nil) + nil) + +(my-assert + (nconc nil nil) + nil) + +(my-assert + (nconc x nil) + (a b c)) + +(my-assert + (nconc nil nil nil nil) + nil) + +(my-assert + (nconc nil nil x nil) + (a b c)) + +(my-assert + (nconc x nil y nil z nil) + (a b c d e f g h i)) + +(my-assert + x + (a b c d e f g h i)) + +(my-assert + y + (d e f g h i)) + +(my-assert + z + (g h i)) + +(my-assert + (eq (cdddr x) + y) + t) + +(my-assert + (eq (cdddr y) + z) + t) + +(my-assert + (nconc (list 1 2) + 'a) + #+xcl error + #+(or clisp akcl allegro cmu sbcl ecls) (1 2 . a) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nconc 'a) + #+xcl error + #+(or clisp akcl allegro cmu sbcl ecls) a + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (setq x + (list 'a 'b 'c) + y + (list 'd 'e 'f)) + (d e f)) + +(my-assert + (nreconc x y) + (c b a d e f)) + +(my-assert + x + #+xcl was-destroyed ; wo kommt denn so was her? + #+clisp (c b a d e f) + #+(or akcl allegro cmu sbcl ecls) (a d e f) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (tailp y x) + t) + +(my-assert + (setq x + (list 'a 'b 'c) + y + (list 'd 'e 'f) + z + (list 'g 'h 'i)) + (g h i)) + +(my-assert + (nreconc) + program-error) + +(my-assert + (nreconc x) + program-error) + +(my-assert + (nreconc nil) + program-error) + +(my-assert + (nreconc nil nil) + nil) + +(my-assert + (nreconc x nil) + (c b a)) + +(my-assert + x + #+xcl was-destroyed + #+clisp (c b a) + #+(or akcl allegro cmu sbcl ecls) (a) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nreconc nil nil nil nil) + program-error) + +(my-assert + (nconc nil 'x) + #+xcl error + #+(or clisp akcl allegro cmu sbcl ecls) x + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (setq aa nil) + nil) + +(my-assert + (push '1 aa) + (1)) + +(my-assert + (push '2 aa) + (2 1)) + +(my-assert + (push '2 aa) + (2 2 1)) + +(my-assert + (setq aa + (list 'b 'a)) + (b a)) + +(my-assert + (pushnew 'a aa) + (b a)) + +(my-assert + (pushnew 'c aa) + (c b a)) + +(my-assert + (setq xxx nil) + nil) + +(my-assert + (pushnew 'c xxx :test 'equal) + (c)) + +(my-assert + (pushnew 'c xxx :test 'equal) + (c)) + +(my-assert + (pushnew (list 'c) xxx :test 'equal) + ((c) c)) + +(my-assert + xxx + ((c) c)) + +(my-assert + (setq xx (list nil + 'kkk)) + (nil kkk)) + +(my-assert + (pushnew 'u (car xx)) + (u)) + +(my-assert + (pushnew 'u + (car xx)) + (u)) + +(my-assert + (pushnew 'v + (car xx)) + (v u)) + +(my-assert + xx + ((v u) kkk)) + +(my-assert + (pushnew (list 'w) + (car xx)) + ((w) + v u)) + +(my-assert + (pushnew (list 'w) + (car xx)) + ((w) + (w) + v u)) + +(my-assert + (pushnew (list 'w) + (car xx) + :test 'equal) + ((w) + (w) + v u)) + +(my-assert + (pushnew (list 'w) + (car xx) + :test-not 'equal) + ((w) + (w) + v u)) + +(my-assert + (setq aa (list 1 2 3)) + (1 2 3)) + +(my-assert + (pop aa) + 1) + +(my-assert + aa + (2 3)) + +(my-assert + (pop aa) + 2) + +(my-assert + (pop aa) + 3) + +(my-assert + (pop aa) + nil) + +(my-assert + (pop aa) + nil) + +(my-assert + (butlast (list 'a 'b 'c)) + (a b)) + +(my-assert + (butlast (list 'a 'b 'c) + 2) + (a)) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) + 3) + (a)) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) + 1) + (a b c)) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) + 0) + (a b c d)) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) + 4) + nil) + +(my-assert + (nbutlast (list 'a 'b 'c 'd) + 6) + nil) + diff --git a/src/ansi-tests/lists153.lisp b/src/ansi-tests/lists153.lisp new file mode 100644 index 000000000..b97b9072b --- /dev/null +++ b/src/ansi-tests/lists153.lisp @@ -0,0 +1,5 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) +;; RPLACA +;; RPLACD + diff --git a/src/ansi-tests/lists154.lisp b/src/ansi-tests/lists154.lisp new file mode 100644 index 000000000..b41d168a8 --- /dev/null +++ b/src/ansi-tests/lists154.lisp @@ -0,0 +1,288 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (subst 'a 'b + '(u b + (b) + c)) + (u a + (a) + c)) + +(my-assert + (subst 'a 'b + '(u b + (b) + c) + :test-not + #'(lambda (x y) + (if (atom y) + (eql x y) + t))) + (a b + (b . a) + a . a)) + +(my-assert + (subst 'a 'b + '(u b + (b) + c) + :test + #'(lambda (x y) + (not (eql x y)))) + a) + +(my-assert + (subst 'a 'b + '(u b + (b) + c) + :test-not + #'(lambda (x y) + (not (eql x y)))) + (u a + (a) + c)) + +(my-assert + (subst 'a 'b + '(u b + (b) + c) + :test-not + #'(lambda (x y) + (not (eql x y))) + :key + #'(lambda (u) + (if (listp u) + (car u)))) + (u . a)) + +(my-assert + (subst-if 'nummmer 'numberp + '((a (7 (v 6))))) + ((a (nummmer (v nummmer))))) + +(my-assert + (subst-if-not 'nummmer 'numberp + '((a (7 (v 6))))) + nummmer) + +(my-assert + (subst-if-not 'nummmer + #'(lambda (x) + (and (listp x) + (numberp x))) + '((a (7 (v 6))))) + nummmer) + +(my-assert + (subst-if-not 'nummmer + #'(lambda (x) + (or (listp x) + (numberp x))) + '((a (7 (v 6))))) + ((nummmer (7 (nummmer 6))))) + +(my-assert + (nsubst 'a 'b + '(u b + (b) + c) + :test-not + #'(lambda (x y) + (if (atom y) + (eql x y) + t))) + (a b + (b . a) + a . a)) + +(my-assert + (nsubst 'a 'b + '(u b + (b) + c) + :test-not + #'(lambda (x y) + (not (eql x y)))) + (u a + (a) + c)) + +(my-assert + (nsubst 'a 'b + '(u b + (b) + c) + :test + #'(lambda (x y) + (not (eql x y)))) + a) + +(my-assert + (nsubst-if 'oo 'numberp + '(a b c + (3 (4) + 0))) + (a b c + (oo (oo) + oo))) + +(my-assert + (nsubst-if-not 'oo 'numberp + '(a b c + (3 (4) + 0))) + oo) + +(my-assert + (nsubst-if-not 'oo + #'(lambda (x) + (or (atom x) + (numberp x))) + '(a b c + (3 (4) + 0))) + oo) + +(my-assert + (nsubst-if-not 'oo + #'(lambda (x) + (and (atom x) + (numberp x))) + '(a b c + (3 (4) + 0))) + oo) + +(my-assert + (nsubst-if-not 'oo + #'(lambda (x) + (or (list x) + (numberp x))) + '(a b c + (3 (4) + 0))) + (a b c + (3 (4) + 0))) + +(my-assert + (nsubst-if-not 'oo + #'(lambda (x) + (or (list x) + (symbolp x))) + '(a b c + (3 (4) + 0))) + (a b c + (3 (4) + 0))) + +(my-assert + (sublis '((a . a1) + (b . b1)) + '(a b)) + (a1 b1)) + +(my-assert + (sublis '((a . a1) + (b . b1)) + '(a b + (b . c))) + (a1 b1 + (b1 . c))) + +(my-assert + (sublis '((a . a1) + (b . b1) + (nil . nil1)) + '(a b + (b . c))) + (a1 b1 + (b1 . c) . + nil1)) + +(my-assert + (sublis '((a . a1) + (b . b1) + (nil . nil1)) + '(a b + (b c))) + (a1 b1 + (b1 c . nil1) . + nil1)) + +(my-assert + (sublis '((a . a1) + (b . b1) + (nil . nil1)) + '(a b + (b c)) + :test-not 'eql) + a1) + +(my-assert + (sublis '((a . a1) + (b . b1) + (nil . nil1)) + '(a b + (b c)) + :test-not + #'(lambda (x y) + (if (atom y) + (eql x y)))) + a1) + +(my-assert + (sublis '(((a) . + uu) + (a . ii)) + '(i (a) + a)) + (i (ii) + ii)) + +(my-assert + (sublis '(((a) . uu) (a . ii)) + '(i (a) a) + :key #'(lambda (x) (if (listp x) (car x)))) + (i ii . ii)) ; key wird angewandt auf: x ein blatt des baumes + +(my-assert + (sublis '(((a) . uu) (a . ii)) + '(i (a) a) + :test #'(lambda (x y) (if (listp y) (eql x (car y))))) + #+(or xcl akcl lucid allegro ecls) (i ii . ii) ; x aus der aliste, y ein blatt des baumes + #+(or clisp cmu sbcl) (i (uu) uu) ; x ein blatt, y aus der aliste + #-(or xcl clisp akcl cmu sbcl lucid allegro ecls) unknown) + +(my-assert + (nsublis '(((a) . uu) (a . ii)) + '(i (a) a) + :key #'(lambda (x) (if (listp x) (car x)))) + (i ii . ii)) ; key wird angewandt auf: x ein blatt des baumes + +(my-assert + (nsublis '(((a) . uu) (a . ii)) + '(i (a) a) + :test #'(lambda (x y) (if (listp x) (equal x y)))) + (i uu . uu)) + +(my-assert + (nsublis '(((a) . uu) (a . ii)) + '(i (a) a) + :test #'(lambda (x y) (if (listp y) (equal x y)))) + (i uu . uu)) + +(my-assert + (nsublis '(((a) . uu) (a . ii)) + '(i (a) a) + :test #'(lambda (x y) (if (listp y) (eql x (car y))))) + #+(or xcl akcl allegro ecls) (i ii . ii) ; x aus der aliste, y ein blatt des baumes + #+(or clisp cmu sbcl lucid) (i (uu) uu) ; x ein blatt, y aus der aliste + #-(or xcl clisp akcl cmu sbcl lucid allegro ecls) unknown) + diff --git a/src/ansi-tests/lists155.lisp b/src/ansi-tests/lists155.lisp new file mode 100644 index 000000000..b017c6045 --- /dev/null +++ b/src/ansi-tests/lists155.lisp @@ -0,0 +1,203 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (member 'a + '((a) + (b) + (a) + (c))) + nil) + +(my-assert + (member 'a + '((a) + (b) + (a) + (c)) + :key 'car) + ((a) + (b) + (a) + (c))) + +(my-assert + (member-if 'numberp + '((a) + (b) + (3) + (c)) + :key 'car) + ((3) + (c))) + +(my-assert + (member-if-not 'numberp + '((8) + (a) + (b) + (3) + (c)) + :key 'car) + ((a) + (b) + (3) + (c))) + +(my-assert + (tailp '(a b) + '(u a b)) + nil) + +(my-assert + (tailp (cddr (setq xx + '(u i a b))) + xx) + t) + +(my-assert + (tailp (cddr (setq xx + '(u i a b))) + xx) + t) + +(my-assert + (adjoin 'a + '(a b c)) + (a b c)) + +(my-assert + (adjoin 'a + '((a) + b c) + :test 'equal) + (a (a) + b c)) + +(my-assert + (adjoin 'a + '((a) + b c) + :test 'equal) + (a (a) + b c)) + +(my-assert + (union '(a b c d) + '(a d i v)) + #+xcl (v i a b c d) + #+(or clisp akcl ecls) (b c a d i v) + #+(or allegro cmu sbcl) (c b a d i v) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nunion '(a b c d) + '(u i b a)) + #+xcl (a b c d u i) + #+(or clisp akcl ecls) (c d u i b a) + #+(or allegro cmu sbcl) (d c u i b a) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nintersection '(a b c d) + '(c d e f g)) + #+(or xcl clisp gcl ecls) (c d) + #+(or allegro cmu sbcl) (d c) + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nintersection '(a b c d) + '(c d e f g) + :test-not 'eql) + #+(or xcl clisp gcl ecls) (a b c d) + #+(or allegro cmu sbcl) (d c b a) + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (set-difference '(a b c d e) + '(d b e)) + #+(or xcl allegro gcl cmu sbcl ecls) (c a) + #+(or clisp (and akcl (not gcl))) (a c) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (set-difference + '(auto anton berta berlin) + '(a) + :test + #'(lambda (x y) + (eql (elt (symbol-name x) + 1) + (elt (symbol-name y) + 1)))) + #+(or xcl allegro) + (berlin berta anton auto) + #-(or xcl allegro) + type-error) + +(my-assert + (set-difference '(anton berta auto berlin) + '(amerilla) + :test + #'(lambda (x y) + (eql (elt (symbol-name x) + 0) + (elt (symbol-name y) + 0)))) + #+(or xcl gcl allegro cmu sbcl) (berlin berta) + #+(or clisp (and akcl (not gcl)) ecls) (berta berlin) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nset-difference '(a b c d) + '(i j c)) + #+(or xcl clisp gcl ecls) (a b d) + #+(or allegro cmu sbcl) (d b a) + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (set-exclusive-or '(a b c d) + '(c a i l)) + #+(or xcl gcl) (d b l i) + #+(or clisp (and akcl (not gcl)) ecls) (b d i l) + #+(or allegro cmu sbcl) (l i d b) + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (set-exclusive-or '(anton anna emil) + '(berta auto august) + :test + #'(lambda (x y) + (eql (elt (symbol-name x) + 0) + (elt (symbol-name y) + 0)))) + #+(or xcl clisp gcl ecls) (emil berta) + #+(or allegro cmu sbcl) (berta emil) + #-(or xcl clisp gcl allegro cmu sbcl ecls) unknown) + +(my-assert + (nset-exclusive-or '(a b c) + '(i a d c)) + (b i d)) + +(my-assert + (subsetp '(a b) + '(b u i a c d)) + t) + +(my-assert + (subsetp '(a b) + '(b u i c d)) + nil) + +(my-assert + (subsetp '(a b) + '(b a u i c d)) + t) + +(my-assert + (subsetp '(a b) + '(a u i c d)) + nil) + diff --git a/src/ansi-tests/lists156.lisp b/src/ansi-tests/lists156.lisp new file mode 100644 index 000000000..da92c84c4 --- /dev/null +++ b/src/ansi-tests/lists156.lisp @@ -0,0 +1,183 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (ACONS 'A 'B NIL) + ((A . B))) + +(my-assert + (ACONS 'A 'B + '((C . D))) + ((A . B) + (C . D))) + +(my-assert + (PAIRLIS '(A B C) + '(1 2)) + #+XCL + ((B . 2) + (A . 1)) + #-XCL + ERROR) + +(my-assert + (PAIRLIS '(A B C) + '(1 2 3)) + #+(or XCL CLISP ALLEGRO cmu sbcl ecls) + ((C . 3) + (B . 2) + (A . 1)) + #+AKCL ((A . 1) (B . 2) (C . 3)) + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl ecls) UNKNOWN) + +(my-assert + (ASSOC 'A + '((B C) + (A U) + (A I))) + (A U)) + +(my-assert + (ASSOC 'A + '((B C) + ((A) + U) + (A I))) + (A I)) + +(my-assert + (ASSOC 'A + '((B C) + ((A) + U) + (A I)) + :KEY + #'(LAMBDA (X) + (IF (LISTP X) + (CAR X)))) + ((A) + U)) + +(my-assert + (ASSOC 'A + '((B C) + A + ((A) + U) + (A I)) + :KEY + #'(LAMBDA (X) + (IF (LISTP X) + (CAR X)))) + #-(or GCL ALLEGRO cmu sbcl) + ((A) U) + #+(or GCL ALLEGRO cmu sbcl) + TYPE-ERROR) + +(my-assert + (ASSOC 'A + '((B C) + A + ((A) + U) + (A I)) + :KEY + #'(LAMBDA (X) + (IF (ATOM X) + X))) + #-(or GCL ALLEGRO cmu sbcl) (A I) + #+(or GCL ALLEGRO cmu sbcl) + TYPE-ERROR) + +(my-assert + (ASSOC 'A + '((B C) + A + ((A) + U) + (A I)) + :TEST + #'(LAMBDA (X Y) + (IF (LISTP Y) + (EQL (CAR Y) + X)))) + #-(or GCL ALLEGRO cmu sbcl) ((A) U) + #+(or GCL ALLEGRO cmu sbcl) + TYPE-ERROR) + +(my-assert + (ASSOC 'A + '((B C) + A + ((A) + U) + (A I)) + :TEST + #'(LAMBDA (X Y) + (IF (ATOM Y) + (EQL Y X)))) + #-(or GCL ALLEGRO cmu sbcl) (A I) + #+(or GCL ALLEGRO cmu sbcl) ERROR) + +(my-assert + (ASSOC 'A + '((B C) + A + ((A) + U) + (A I)) + :TEST-NOT + #'(LAMBDA (X Y) + (IF (ATOM Y) + (EQL Y X)))) + #-ALLEGRO (B C) + #+ALLEGRO ERROR) + +(my-assert + (ASSOC-IF 'NUMBERP + '((A . 3) + (3 . A))) + (3 . A)) + +(my-assert + (ASSOC-IF 'SYMBOLP + '((A . 3) + (3 . A))) + (A . 3)) + +(my-assert + (ASSOC-IF-NOT 'SYMBOLP + '((A . 3) + (3 . A))) + (3 . A)) + +(my-assert + (ASSOC-IF-NOT 'NUMBERP + '((A . 3) + (3 . A))) + (A . 3)) + +(my-assert + (RASSOC 'A + '((1 . B) + (2 . A))) + (2 . A)) + +(my-assert + (RASSOC-IF 'SYMBOLP + '((1 . B) + (2 . A))) + (1 . B)) + +(my-assert + (RASSOC-IF 'SYMBOLP + '((1 . 3) + (2 . A))) + (2 . A)) + +(my-assert + (RASSOC-IF-NOT 'SYMBOLP + '((1 . 3) + (2 . A))) + (1 . 3)) + diff --git a/src/ansi-tests/loop.lisp b/src/ansi-tests/loop.lisp new file mode 100644 index 000000000..3a285b149 --- /dev/null +++ b/src/ansi-tests/loop.lisp @@ -0,0 +1,937 @@ +;;; based on v1.5 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (loop for x from 1 to 9 + for y = nil then x + collect (list x y) + ) + ((1 NIL) (2 2) (3 3) (4 4) (5 5) (6 6) (7 7) (8 8) (9 9))) + +(my-assert + (loop for x from 1 to 9 + and y = nil then x + collect (list x y) + ) + ((1 NIL) (2 1) (3 2) (4 3) (5 4) (6 5) (7 6) (8 7) (9 8))) + +(my-assert + (with-output-to-string (*standard-output*) + (loop as i from 1 to 5 + do (print i) + ) ) + " +1 +2 +3 +4 +5 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i from 10 downto 1 by 3 + do (print i) + ) ) + " +10 +7 +4 +1 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop as i below 5 + do (print i) + ) ) + " +0 +1 +2 +3 +4 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for item in '(1 2 3 4 5) + do (print item) + ) ) + " +1 +2 +3 +4 +5 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for item in '(1 2 3 4 5) by #'cddr + do (print item) + ) ) + " +1 +3 +5 ") + +(my-assert + (loop for (item . x) (t . fixnum) in '((A . 1) (B . 2) (C . 3)) + unless (eq item 'B) sum x + ) + 4) + +(my-assert + (loop for sublist on '(a b c d) + collect sublist + ) + ((A B C D) (B C D) (C D) (D))) + +(my-assert + (with-output-to-string (*standard-output*) + (loop for (item) on '(1 2 3) + do (print item) + ) ) + " +1 +2 +3 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for item in '(1 2 3) + do (print item) + ) ) + " +1 +2 +3 ") + +(my-assert + (loop for i below 5 + for j = 10 then i + collect j + ) + (10 1 2 3 4)) + +(my-assert + (loop for i below 5 + for j = i + collect j + ) + (0 1 2 3 4)) + +(my-assert + (loop for item = 1 then (+ item 10) + repeat 5 + collect item + ) + (1 11 21 31 41)) + +(my-assert + (loop for char across (the simple-string "Hello") + collect char + ) + (#\H #\e #\l #\l #\o)) + +(my-assert + (with-output-to-string (*standard-output*) + (loop repeat 3 + do (write-line "What I say three times is true") + ) ) + "What I say three times is true +What I say three times is true +What I say three times is true +") + +(my-assert + (with-output-to-string (*standard-output*) + (loop repeat -15 + do (write-line "What you see is what you expect") + ) ) + "") + +#|;; FOR clauses should come before WHILE clauses +(let ((stack '(a b c d e f))) + (loop while stack + for item = (length stack) then (pop stack) + collect item + ) ) +(6 A B C D E F) +|# + +(my-assert + (loop for i fixnum from 3 + when (oddp i) collect i + while (< i 5) + ) + (3 5)) + +(my-assert + (loop for i from 0 to 10 + always (< i 11) + ) + T) + +(my-assert + (loop for i from 0 to 10 + never (> i 11) + ) + T) + +(my-assert + (loop for i from 0 + thereis (when (> i 10) i) + ) + 11) + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i from 0 to 10 + always (< i 9) + finally (print "You won't see this") + ) ) + "") + +(my-assert + (with-output-to-string (*standard-output*) + (loop never t + finally (print "You won't see this") + ) ) + "") + +(my-assert + (with-output-to-string (*standard-output*) + (loop thereis "Here is my value" + finally (print "You won't see this") + ) ) + "") + +(my-assert + (loop thereis "Here is my value" + finally (print "You won't see this") + ) + "Here is my value") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i from 1 to 10 + thereis (> i 11) + finally (print i) + ) ) + " +11 ") + +(my-assert + (let (everest chocorua sahara) + (defstruct mountain height difficulty (why "because it is there")) + (setq everest (make-mountain :height '(2.86e-13 parsecs))) + (setq chocorua (make-mountain :height '(1059180001 microns))) + (defstruct desert area (humidity 0)) + (setq sahara (make-desert :area '(212480000 square furlongs))) + (loop for x in (list everest sahara chocorua) + thereis (and (mountain-p x) (mountain-height x)) + ) ) + (2.86e-13 parsecs)) + +(my-assert + (with-output-to-string (*standard-output*) + (loop for (month date-list) in '((january (24 28)) (february (17 29 12))) + do (loop for date in date-list + do (case date + (29 (when (eq month 'february) (loop-finish))) + ) + do (format t "~:(~A~) ~A~%" month date) + ) ) ) + "January 24 +January 28 +February 17 +") + +(my-assert + (loop for i in '(1 2 3 stop-here 4 5 6) + when (symbolp i) do (loop-finish) + count i + ) + 3) + +(my-assert + (loop for i in '(1 2 3 stop-here 4 5 6) + until (symbolp i) + count i + ) + 3) + +(my-assert + (loop for name in '(fred sue alice joe june) + for kids in '((bob ken) () () (kris sunshine) ()) + collect name + append kids + ) + (FRED BOB KEN SUE ALICE JOE KRIS SUNSHINE JUNE)) + +(my-assert + (multiple-value-list + (loop for name in '(fred sue alice joe june) + as age in '(22 26 19 20 10) + append (list name age) into name-and-age-list + count name into name-count + sum age into total-age + finally + (return (values (round total-age name-count) name-and-age-list)) + ) ) + (19 (FRED 22 SUE 26 ALICE 19 JOE 20 JUNE 10))) + +(my-assert + (loop for i in '(bird 3 4 turtle (1 . 4) horse cat) + when (symbolp i) collect i + ) + (BIRD TURTLE HORSE CAT)) + +(my-assert + (loop for i from 1 to 10 + if (oddp i) collect i + ) + (1 3 5 7 9)) + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i in '(a b c d) by #'cddr + collect i into my-list + finally (print my-list) + ) ) + " +(A C) ") + +(my-assert + (loop for x in '((a) (b) ((c))) + append x + ) + (A B (C))) + +(my-assert + (loop for i upfrom 0 + as x in '(a b (c)) + nconc (if (evenp i) (list x) '()) + ) + (A (C))) + +(my-assert + (loop for i in '(a b nil c nil d e) + count i + ) + 5) + +(my-assert + (loop for i fixnum in '(1 2 3 4 5) + sum i + ) + 15) + +(my-assert + (let ((series '(1.2 4.3 5.7))) + (loop for v in series + sum (* 2.0 v) + ) ) + 22.4) + +(my-assert + (loop for i in '(2 1 5 3 4) + maximize i + ) + 5) + +(my-assert + (loop for i in '(2 1 5 3 4) + minimize i + ) + 1) + +(my-assert + (let ((series '(1.2 4.3 5.7))) + (loop for v in series + maximize (round v) fixnum + ) ) + 6) + +(my-assert + (let ((series '(1.2 4.3 5.7))) + (loop for v in series + minimize (round v) into result fixnum + finally (return result) + ) ) + 1) + +(my-assert + (loop with a = 1 + with b = (+ a 2) + with c = (+ b 3) + with d = (+ c 4) + return (list a b c d) + ) + (1 3 6 10)) + +(my-assert + (loop with a = 1 + and b = 2 + and c = 3 + and d = 4 + return (list a b c d) + ) + (1 2 3 4)) + +(my-assert + (let ((a 5) (b 10) (c 1729)) + (loop with a = 1 + and b = (+ a 2) + and c = (+ b 3) + and d = (+ c 4) + return (list a b c d) + ) ) + (1 7 13 1733)) + +(my-assert + (loop with (a b c) (float integer float) + return (format nil "~A ~A ~A" a b c) + ) + "0.0 0 0.0") + +(my-assert + (loop with (a b c) float + return (format nil "~A ~A ~A" a b c) + ) + "0.0 0.0 0.0") + +(my-assert + (let ((numbers-list '(3 2 4 6 1 7 8)) (results nil)) + (cons + (with-output-to-string (*standard-output*) + (loop for i in numbers-list + when (oddp i) + do (print i) + and collect i into odd-numbers + and do (terpri) + else + collect i into even-numbers + finally (setq results (list odd-numbers even-numbers)) + ) ) + results + ) ) + (" +3 + +1 + +7 +" + (3 1 7) (2 4 6 8))) + +(my-assert + (loop for i in '(1 2 3 4 5 6) + when (and (> i 3) i) + collect it + ) + (4 5 6)) + +(my-assert + (loop for i in '(1 2 3 4 5 6) + when (and (> i 3) i) + return it + ) + 4) + +(my-assert + (loop for i in '(1 2 3 4 5 6) + thereis (and (> i 3) i) + ) + 4) + +(my-assert + (with-output-to-string (*standard-output*) + (loop for x from 0 to 3 + do (print x) + if (zerop (mod x 2)) + do (write-string " a") + and + if (zerop (floor x 2)) + do (write-string " b") + and + do (write-string " c") + ) ) + " +0 a b c +1 +2 a +3 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for x from 0 to 3 + do (print x) + if (zerop (mod x 2)) + do (write-string " a") + and + if (zerop (floor x 2)) + do (write-string " b") + end + and + do (write-string " c") + ) ) + " +0 a b c +1 +2 a c +3 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i from 1 to 5 + do (print i) + ) ) + " +1 +2 +3 +4 +5 ") + +(my-assert + (with-output-to-string (*standard-output*) + (loop for i from 1 to 4 + do (print i) + (print (* i i)) + ) ) + " +1 +1 +2 +4 +3 +9 +4 +16 ") + +(my-assert + (loop for item in '(1 2 3 a 4 5) + when (not (numberp item)) + return (format nil "non-numeric value: ~S" item) + ) + "non-numeric value: A") + +(my-assert + (loop for item in '(1 2 3 a 4 5) + when (not (numberp item)) + do (return (format nil "non-numeric value: ~S" item)) + ) + "non-numeric value: A") + +(my-assert + (loop for numlist in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + for a integer = (first numlist) + for b integer = (second numlist) + for c float = (third numlist) + collect (list c b a) + ) + ((4.0 2 1) (8.3 6 5) (10.4 9 8))) + +;; According to the BNF syntax, "and" must not be followed by "for". But +;; ANSI CL section 6.1.1.5.1 contains ambiguous wording, and this example +;; appears in CLtL2 p. 743, we keep it. +(my-assert + (loop for numlist in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + for a integer = (first numlist) + and for b integer = (second numlist) + and for c float = (third numlist) + collect (list c b a) + ) + #-(OR CMU SBCL) ((4.0 2 1) (8.3 6 5) (10.4 9 8)) + #+(OR CMU SBCL) ERROR) + +(my-assert + (loop for numlist in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + for a integer = (first numlist) + and b integer = (second numlist) + and c float = (third numlist) + collect (list c b a) + ) + ((4.0 2 1) (8.3 6 5) (10.4 9 8))) + +(my-assert + (loop for (a b c) (integer integer float) in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + collect (list c b a) + ) + ((4.0 2 1) (8.3 6 5) (10.4 9 8))) + +(my-assert + (loop for (a b c) float in '((1.0 2.0 4.0) (5.0 6.0 8.3) (8.0 9.0 10.4)) + collect (list c b a) + ) + ((4.0 2.0 1.0) (8.3 6.0 5.0) (10.4 9.0 8.0))) + +(my-assert + (loop with (a b) float = '(1.0 2.0) + and (c d) integer = '(3 4) + and (e f) + return (list a b c d e f) + ) + (1.0 2.0 3 4 NIL NIL)) + +(my-assert + (loop for (a nil b) = '(1 2 3) + do (return (list a b)) + ) + (1 3)) + +(my-assert + (loop for (x . y) = '(1 . 2) + do (return y) + ) + 2) + +(my-assert + (loop for ((a . b) (c . d)) of-type ((float . float) (integer . integer)) + in '(((1.2 . 2.4) (3 . 4)) ((3.4 . 4.6) (5 . 6))) + collect (list a b c d) + ) + ((1.2 2.4 3 4) (3.4 4.6 5 6))) + +(my-assert + (loop for buffer in '("\"Hello\"" "\"unterminated" "nothing") + collect + (loop initially (unless (char= (char buffer 0) #\") (loop-finish)) + for i fixnum from 1 below (length buffer) + when (char= (char buffer i) #\") + return i + ) ) + (6 NIL NIL)) + +(my-assert + (let (result) + (list + (with-output-to-string (*standard-output*) + (setq result + (loop for i from 1 to 10 + when (> i 5) + collect i + finally (print i) + ) ) ) + result + ) ) + (" +11 " (6 7 8 9 10))) + +(my-assert + (multiple-value-list + (loop for i from 1 to 10 + when (> i 5) + collect i into number-list + and count i into number-count + finally (return (values number-count number-list)) + ) ) + (5 (6 7 8 9 10))) + +(my-assert + (let (result) + (list + (with-output-to-string (*standard-output*) + (setq result + (loop named max + for i from 1 to 10 + do (print i) + do (return-from max 'done) + ) ) ) + result + ) ) + (" +1 " DONE)) + +;;; The following tests are not mandatory according to dpANS or ANSI CL, +;;; but that's how users expect the LOOP macro to work, so we check them. + +(my-assert + (loop for i = 0 + for j to 2 + collect j + ) + (0 1 2)) + +(my-assert + (loop for i in '(1 2) + for j = i + for k = j + collect (list i j k) + ) + ((1 1 1) (2 2 2))) + +(my-assert + (loop for idx upfrom 0 below 5 + for char = (aref "Error" idx) + collect char + ) + (#\E #\r #\r #\o #\r)) + +(my-assert + (let ((hash-table (make-hash-table))) + (setf (gethash 1 hash-table) 100) + (setf (gethash 2 hash-table) 200) + (sort + (loop for key being each hash-key in hash-table using (hash-value val) + for key+1 = (1+ key) + collect (list key key+1 val)) + #'< + :key #'car + ) ) + ((1 2 100) (2 3 200))) + +(my-assert + (loop for i across '#(1 2 3 4) + for j = (1+ i) + collect (list i j) + ) + ((1 2) (2 3) (3 4) (4 5))) + +(my-assert + (loop for i in '() + for j = (1+ i) + collect j + ) + nil) + +(my-assert + (loop for i across '#() + for j = (1+ i) + collect j + ) + nil) + +(my-assert + (loop for x = t + for y in '(A B C) + for z = t + collect y + ) + (A B C)) + +(my-assert + (loop for x = t + for y across '#(A B C) + for z = t + collect y + ) + (A B C)) + +(my-assert + (loop for x = t + for y in () + for z = t + collect y + ) + nil) + +(my-assert + (loop for x = t + for y across '#() + for z = t + collect y + ) + nil) + +(my-assert + (let ((hash-table (make-hash-table))) + (setf (gethash 1 hash-table) 100) + (setf (gethash 2 hash-table) 200) + (sort + (loop for x = t + for key being each hash-key in hash-table using (hash-value val) + for key+1 = (1+ key) + for z = t + collect (list key key+1 val)) + #'< + :key #'car + ) ) + ((1 2 100) (2 3 200))) + +(my-assert + (loop for i from 1 to 0 + collect i + ) + nil) + +(my-assert + (let ((hash-table (make-hash-table))) + (setf (gethash 1 hash-table) 100) + (setf (gethash 2 hash-table) 200) + (sort + (loop for val being each hash-value in hash-table + collect val) + #'< + ) ) + (100 200)) + +(my-assert + (let ((hash-table (make-hash-table))) + (setf (gethash 1 hash-table) 100) + (setf (gethash 2 hash-table) 200) + (sort + (loop for val being each hash-value in hash-table + for deriv-val = (/ 1 val) + collect deriv-val) + #'< + ) ) + (1/200 1/100)) + +(my-assert + (let ((hash-table (make-hash-table))) + (setq i 123456789) + (setf (gethash 1 hash-table) 100) + (setf (gethash 2 hash-table) 200) + (loop for i across '#(1 2 3 4 5 6) + collect i) + (loop for i in '(1 2 3 4 5 6) + collect i) + (loop for i being each hash-key of hash-table + collect i) + (loop for i being each present-symbol of *package* + collect i) + i + ) + 123456789) + +(my-assert + (loop for x on '(3 4 5) + for y = (car x) + for z in '(a b c) + collect z + ) + (a b c)) + +(my-assert + (loop for x across '#(3 4 5) + for y = (1+ x) + for z across '#(a b c) + collect (list x y z) + ) + ((3 4 a) (4 5 b) (5 6 c))) + +(my-assert + (loop for x across '#() + for y = x + for z across '#(a b c) + collect (list x y z) + ) + nil) + +(my-assert + (loop for x across '#(1 2 3) + for y = x + for z across '#() + collect (list x y z) + ) + nil) + +(my-assert + (loop for x across '#(1 2 3) + for y = (1+ x) + for z across '#(a b) + collect (list x y z) + ) + ((1 2 a) (2 3 b))) + +(my-assert + (loop for x across '#(1 2) + for y = (1+ x) + for z across '#(a b c) + collect (list x y z) + ) + ((1 2 a) (2 3 b))) + +(my-assert + (let ((package (make-package "LOOP-TEST"))) + (intern "blah" package) + (let ((blah2 (intern "blah2" package))) + (export blah2 package) + ) + (list + (sort + (loop for sym being each present-symbol of package + for sym-name = (symbol-name sym) + collect sym-name + ) + #'string< + ) + (sort + (loop for sym being each external-symbol of package + for sym-name = (symbol-name sym) + collect sym-name + ) + #'string< + ) ) ) + (("blah" "blah2") ("blah2"))) + +(my-assert + (let ((ht (make-hash-table))) + (loop for key being each hash-key of ht + for value = (gethash key ht) + collect (list key value) + ) ) + nil) + +(my-assert + (let ((ht (make-hash-table))) + (loop for dummy = (+ 1 2) + for key being each hash-key of ht + collect (list key) + ) ) + nil) + +;;; Three more tests, found by Russell Senior. +;;; They are justified by ANSI CL 6.1.1.4 and 6.1.2.1.5. + +(my-assert + (let ((list '(1 2 3))) + (loop for x in list + and y = nil then x + collect (list x y))) + ((1 NIL) (2 1) (3 2))) + +(my-assert + (let ((list '(1 2 3))) + (loop for x in list + for y = nil then x + collect (list x y))) + ((1 NIL) (2 2) (3 3))) + +(my-assert + (let ((list '(1 2 3))) + (loop for x in list + for y = nil then x + and z = nil then y + collect (list x y z))) + ((1 NIL NIL) (2 2 NIL) (3 3 2))) + +;;; One more test, found by Lennart Staflin. + +(my-assert + (loop repeat 4 for x = (+ 1 1) collect x) + (2 2 2 2)) + +;;; Tests from ANSI CL section 6.1.2.1.1. + +(my-assert + (let ((x 1)) (loop for i from x by (incf x) to 10 collect i)) + (1 3 5 7 9)) + +(my-assert + (let ((x 1)) (loop for i by (incf x) from x to 10 collect i)) + (2 4 6 8 10) + "This should be the same as: +(let ((x 1)) (loop for i from x to 10 by (incf x) collect i)) +it is legal to have by first: +arithmetic-up::= [[{from | upfrom} form1 | {to | upto | below} form2 | by form3]]+ ") + +(my-assert + (loop for i from 1 to 5 collect i into c collect (copy-list c)) + ((1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5))) + +;; Clean up. +(my-assert + (progn (delete-package "LOOP-TEST") t) + T) + diff --git a/src/ansi-tests/macro8.lisp b/src/ansi-tests/macro8.lisp new file mode 100644 index 000000000..d3b3099e5 --- /dev/null +++ b/src/ansi-tests/macro8.lisp @@ -0,0 +1,141 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +;; testen der macrofunktionen kapitel 8 +;; ------------------------------------ + + +;; 8.1 +;; macro-function | defmacro + + +(my-assert + (and (macro-function 'push) T) + T) + +(my-assert + (and (macro-function 'member) T) + NIL) + +(my-assert + (defmacro arithmetic-if (test neg-form zero-form pos-form) + (let ((var (gensym))) + `(let ((,var ,test)) + (cond ((< ,var 0) ,neg-form) + ((= ,var 0) ,zero-form) + (T ,pos-form))))) + arithmetic-if) + + +(my-assert + (and (macro-function 'arithmetic-if) T) + T) + +(my-assert + (setf x 8) + 8) + +(my-assert + (arithmetic-if (- x 4)(- x)(LIST "ZERO") x) + 8) + + +(my-assert + (setf x 4) + 4) + +(my-assert + (arithmetic-if (- x 4)(- x)(LIST "ZERO")x) + ("ZERO")) + + +(my-assert + (setf x 3) + 3) + +(my-assert + (arithmetic-if (- x 4)(- x)(LIST "ZERO")x) + -3) + + + +(my-assert + (defmacro arithmetic-if (test neg-form &optional zero-form pos-form) + (let ((var (gensym))) + `(let ((,var ,test)) + (cond ((< ,var 0) ,neg-form) + ((= ,var 0) ,zero-form) + (T ,pos-form))))) + arithmetic-if) + + +(my-assert + (setf x 8) + 8) + +(my-assert + (arithmetic-if (- x 4)(- x)) + nil) + + +(my-assert + (setf x 4) + 4) + +(my-assert + (arithmetic-if (- x 4)(- x)) + NIL) + + +(my-assert + (setf x 3) + 3) + +(my-assert + (arithmetic-if (- x 4)(- x)) + -3) + +(my-assert + (defmacro halibut ((mouth eye1 eye2) + ((fin1 length1)(fin2 length2)) + tail) + `(list ,mouth ,eye1 ,eye2 ,fin1 ,length1 ,fin2 ,length2 ,tail)) + halibut) + +(my-assert + (setf m 'red-mouth + eyes '(left-eye . right-eye) + f1 '(1 2 3 4 5) + f2 '(6 7 8 9 0) + my-favorite-tail '(list of all parts of tail)) + (list of all parts of tail)) + + + +(my-assert + (halibut (m (car eyes)(cdr eyes)) + ((f1 (length f1))(f2 (length f2))) + my-favorite-tail) + (RED-MOUTH LEFT-EYE RIGHT-EYE (1 2 3 4 5) 5 (6 7 8 9 0) 5 + (LIST OF ALL PARTS OF TAIL))) + +;; 8.2 +;; macroexpand | macroexpand-1 + + +(my-assert + (ecase 'otherwise + (otherwise 4)) + 4 + "This is bad style, but perfectly legal!!") + +;; Issue MACRO-FUNCTION-ENVIRONMENT:YES +(my-assert + (macrolet ((foo (&environment env) + (if (macro-function 'bar env) + ''yes + ''no))) + (list (foo) + (macrolet ((bar () :beep)) + (foo)))) + (no yes)) diff --git a/src/ansi-tests/map.lisp b/src/ansi-tests/map.lisp new file mode 100644 index 000000000..274439f56 --- /dev/null +++ b/src/ansi-tests/map.lisp @@ -0,0 +1,294 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (setf a-vector (make-array 10)) + #+(or XCL cmu sbcl) #(0 0 0 0 0 0 0 0 0 0) + #+(or CLISP AKCL ALLEGRO ecls) #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) + #-(or XCL CLISP AKCL ALLEGRO cmu sbcl ecls) UNKNOWN) + +(my-assert + (do ((i 0 (1+ i)) + (n (length a-vector))) + ((= i n)) + (when (null (aref a-vector i)) + (setf (aref a-vector i) 0))) + nil) + +(my-assert + (setq liste '(a b c d)) + (a b c d)) + +(my-assert + (setq x 'anfangswert-von-x) + anfangswert-von-x) + +(my-assert + (do ((x liste (cdr x)) + (oldx x x)) + ((null x)) + (print oldx) (print x)) + nil) + +(my-assert + (defun list-reverse(list) + (do ((x list (cdr x)) + (y '() (cons (car x) y))) + ((endp x) y))) + list-reverse) + +(my-assert + (list-reverse '(a b c d)) + (d c b a)) + +(my-assert + (setq foo '(a b c d)) + (a b c d)) + +(my-assert + (setq bar '(1 2 3 4)) + (1 2 3 4)) + +(my-assert + (defun fkt(a b) (cons a b)) + fkt) + +;; mapcar + +(my-assert + (mapcar #'abs '(3 -4 2 -5 -6)) + (3 4 2 5 6)) + +(my-assert + (mapcar #'cons '(a b c) '(1 2 3)) + ((a . 1) (b . 2) (c . 3))) + + +(my-assert + (mapcar #'fkt foo bar) + ((a . 1)(b . 2)(c . 3)(d . 4))) + +(my-assert + (do ((x foo (cdr x)) + (y bar (cdr y)) + (z '() (cons (fkt (car x) (car y)) z))) + ((or (null x) (null y)) + (nreverse z))) + ((a . 1)(b . 2)(c . 3)(d . 4))) + +;; dolist +(my-assert + (let ((l '(1 2 3)) + (r 0)) + (dolist (x l r) + (setf r (+ r x)) )) + 6) + + +;; dolist +(my-assert + (let ((l '(1 2 3))) + (dolist (x l)(if (> 0 x)(incf x)(return 10)))) + 10) + +(my-assert + (let ((l '(1 2 3))) + (dolist (x l )(incf x))) + nil) + +;; dotimes + +(my-assert + (let ((s 0)) + (dotimes (i (+ 1 9)s)(setf s (+ s i)))) + 45) + + +(my-assert + (dolist (x '(a b c d)) (prin1 x) (princ " ")) + nil) + +(my-assert + (defun palindromep (string &optional + (start 0) + (end (length string))) + (dotimes (k (floor (- end start) 2) t) + (unless (char-equal (char string (+ start k)) + (char string (- end k 1))) + (return nil)))) + palindromep) + +(my-assert + (palindromep "Able was I ere I saw Elba") + t) + +(my-assert + (palindromep "einnegermitgazellezagtimregennie") + t) + +(my-assert + (palindromep "eisgekuehlter bommerlunder") + nil) + +(my-assert + (palindromep (remove-if-not #'alpha-char-p + "A man, a plan, a canal -- Panama")) + t) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X) (LIST X))) (QUOTE (A B C))) + ((A) (B) (C))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y) (LIST X Y))) (QUOTE (A B C)) (QUOTE + (1 2 3))) + ((A 1) (B 2) (C 3))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y) (LIST X Y))) (QUOTE (A B C)) (QUOTE + (1 2))) + ((A 1) (B 2))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y) (LIST X Y))) (QUOTE (C)) (QUOTE (1 + 2))) + ((C 1))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y Z) (LIST X Y))) (QUOTE (C)) (QUOTE (1 + 2)) (U V W)) + ERROR) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y Z) (LIST X Y))) (QUOTE (C)) (QUOTE (1 + 2)) + (QUOTE (U V W))) + ((C 1))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y Z) (LIST X Y))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U V W))) + ((A 1) (B 2) (C 3))) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U V W))) + ((A 1 U) (B 2 V) (C 3 W))) + +;; mapc +(my-assert + (mapc #'abs '(3 -4 2 -5 -6)) + (3 -4 2 -5 -6)) + +(my-assert + (MAPC (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + (A B C)) + +(my-assert + (MAPCAR (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + ((A 1 U) (B 2 I) (C 3 V))) + +(my-assert + (mapl #'(lambda (x y)(cons x y))'(a b c d)'(1 2 3 4)) + (a b c d)) + +(my-assert + (MAPL (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + (A B C)) + +;; maplist + +(my-assert + (maplist #'(lambda (x)(cons 'foo x))'(a b c d)) + ((foo a b c d)(foo b c d)(foo c d)(foo d))) + + +(my-assert + (maplist #'(lambda (x) (if (member (car x)(cdr x)) 0 1)) + '(a b a c d b c)) + (0 0 1 0 1 1 1)) + + +(my-assert + (MAPLIST (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) + (QUOTE (1 2 3)) (QUOTE (U I V))) + (((A B C) (1 2 3) (U I V)) ((B C) (2 3) (I V)) ((C) (3) (V)))) + +(my-assert + (MAPLIST (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) + (QUOTE (1 2 3)) (QUOTE (U I))) + (((A B C) (1 2 3) (U I)) ((B C) (2 3) (I)))) + +(my-assert + (MAPLIST (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2)) + (QUOTE (U I V))) + (((A B C) (1 2) (U I V)) ((B C) (2) (I V)))) + +(my-assert + (MAPLIST (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + (((A B) (1 2 3) (U I V)) ((B) (2 3) (I V)))) + +;; mapcon + +(my-assert + (mapcon #'(lambda (x)(and (oddp (car x))(list (car x))))'(5 4 3 2 1)) + (5 3 1)) + + +(my-assert + (MAPCON (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + ((A B) (1 2 3) (U I V) (B) (2 3) (I V))) + +(my-assert + (MAPCON (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + ((A B C) (1 2 3) (U I V) (B C) (2 3) (I V) (C) (3) (V))) + +;; mapcan + +(my-assert + (mapcan #'(lambda (x)(and (numberp x)(list x)))'(a 1 b c 3 4 d 5)) + (1 3 4 5)) + +(my-assert + (MAPCAN (FUNCTION (LAMBDA (X Y Z) (LIST X Y Z))) (QUOTE (A B C)) (QUOTE + (1 2 3)) + (QUOTE (U I V))) + (A 1 U B 2 I C 3 V)) + +(my-assert + (MAPCAN (FUNCTION (LAMBDA (X Y) (LIST X Y))) (QUOTE (A B C)) (QUOTE + (1 2 3))) + (A 1 B 2 C 3)) + +(my-assert + (MAPCAN (FUNCTION (LAMBDA (X) (LIST X))) (QUOTE (A B C))) + (A B C)) + +(my-assert + (MAPCON (FUNCTION (LAMBDA (X) (LIST X))) (QUOTE (A B C))) + ((A B C) (B C) (C))) + +(my-assert + (MAPCON (FUNCTION (LAMBDA (X Y) (LIST X Y))) (QUOTE (A B C)) (QUOTE + (1 2))) + ((A B C) (1 2) (B C) (2))) + +(my-assert + (MAPCON (FUNCTION (LAMBDA (X) (LIST X))) (QUOTE (A B C))) + ((A B C) (B C) (C))) + diff --git a/src/ansi-tests/mop.lisp b/src/ansi-tests/mop.lisp new file mode 100644 index 000000000..5fe33ef7d --- /dev/null +++ b/src/ansi-tests/mop.lisp @@ -0,0 +1,34 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) +;; Test some MOP-like CLOS features + +#+clisp +(my-assert + (progn + (defstruct rectangle1 (x 0.0) (y 0.0)) + (defclass counted1-class (structure-class) + ((counter :initform 0)) #+CLISP (:metaclass structure-class)) + (defclass counted1-rectangle (rectangle1) () (:metaclass counted1-class)) + (defmethod make-instance :after ((c counted1-class) &rest args) + (incf (slot-value c 'counter))) + (slot-value (find-class 'counted1-rectangle) 'counter) + (make-instance 'counted1-rectangle) + (slot-value (find-class 'counted1-rectangle) 'counter) + ) + 1) + +#+clisp +(my-assert + (progn + (defclass rectangle2 () + ((x :initform 0.0 :initarg x) (y :initform 0.0 :initarg y))) + (defclass counted2-class (standard-class) + ((counter :initform 0)) #+CLISP (:metaclass structure-class)) + (defclass counted2-rectangle (rectangle2) () (:metaclass counted2-class)) + (defmethod make-instance :after ((c counted2-class) &rest args) + (incf (slot-value c 'counter))) + (slot-value (find-class 'counted2-rectangle) 'counter) + (make-instance 'counted2-rectangle) + (slot-value (find-class 'counted2-rectangle) 'counter) + ) + 1) diff --git a/src/ansi-tests/new-bugs.lisp b/src/ansi-tests/new-bugs.lisp new file mode 100644 index 000000000..210ed03f1 --- /dev/null +++ b/src/ansi-tests/new-bugs.lisp @@ -0,0 +1,37 @@ +;;; -*- mode: lisp -*- +(proclaim '(special log)) +(in-package :cl-user) + + +;; From: Gary Bunting + +(my-assert + (setf xx (expt 3 32)) + 1853020188851841) + +(my-assert + (* xx xx) + 3433683820292512484657849089281) + +;; paul + +(my-assert + (defun bugged (x) + (labels ((f (y &optional trouble) ; <<< or &key or &rest .. + (if y + (let ((a (pop y))) + (f a))))))) + BUGGED) + +(my-assert + (defun tst () + (labels + ((eff (&key trouble) + (eff) + )) + ;;(eff :trouble nil) ;<< this works + (eff);; << this causes assert failure + )) + tst) + + diff --git a/src/ansi-tests/number.lisp b/src/ansi-tests/number.lisp new file mode 100644 index 000000000..df3404291 --- /dev/null +++ b/src/ansi-tests/number.lisp @@ -0,0 +1,14696 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) + +;;; Michael Stoll 23. 3. 1993 + +;; ==== B I G N U M S ==== + +;; ---- Test von + --- + +(my-assert + (+ 17009115185923538769 -12047631083067675031) + 4961484102855863738) + +(my-assert + (+ 12677011568664239747 3269056182420253574) + 15946067751084493321) + +(my-assert + (+ 9315504781982082433 13857624532376678678) + 23173129314358761111) + +(my-assert + (+ 15226508728194069537 11481952022080775416) + 26708460750274844953) + +(my-assert + (+ 7461641943684774743 12249026721402718630) + 19710668665087493373) + +(my-assert + (+ 1180469445886971055 -3208456171287181032) + -2027986725400209977) + +(my-assert + (+ 18358552990465743315 221529797579218180385160273426219343697) + 221529797579218180403518826416685087012) + +(my-assert + (+ -14819874956616484359 30498815629431206969122152847973230849) + 30498815629431206954302277891356746490) + +(my-assert + (+ -11781881800334342169 112219460388643619332860331282276228017) + 112219460388643619321078449481941885848) + +(my-assert + (+ 3570694277032201957 284821691832196381859344006870088122712) + 284821691832196381862914701147120324669) + +(my-assert + (+ -17005463295060938595 69162171850264911722979835561124066203) + 69162171850264911705974372266063127608) + +(my-assert + (+ 15647113311796203488 150750467185419235519670165664526735459) + 150750467185419235535317278976322938947) + +(my-assert + (+ -14330150541101371097 -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886421335353882155416908) + -13054027994001826312503071338715966858478218093171762021549815587520723118772963817341751396703629529810372702877555022105594068768886435665504423256788005) + +(my-assert + (+ 7406427184711759740 -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336084100766391093756252) + -4059250217961011548005203450962458026528281798230141192186669580689721046971433745892994467792118611646113962840750314719233572760336076694339206381996512) + +(my-assert + (+ 8819522415901031498 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363793325150672647162846) + 7274905269237471130619913887005155660991437201841760414347836177003483932007334374478344594178179032728521106519295465031750530183363802144673088548194344) + +(my-assert + (+ -7242932332215698200 -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159009687703010657137320) + -10558564312909325527488520195600871241245891651644550509993750377630234801225525279855157008009255586978047154906058790342845859331159016930635342872835520) + +(my-assert + (+ 9794320575955609492 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470325394342993771343357) + 13380937715397052566925484435342184213544885758759259410983243841206628594840271850190097746775475837233042430565529099681550277688470335188663569726952849) + +(my-assert + (+ -18404048401680891243 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224482801864925665484770) + 6690884608978704096379677348142836785900717005050936986370615083929607190833180925295418079551348559691161519822750772440155040888224464397816523984593527) + +(my-assert + (+ -10763220363947284865 -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521301209899829037444385) + -30985722824355332972176356513316569304601382411274079243859710673739383446566598659878378034375348869471278415635671865753349734809209959160389615096293457362383744562507969316522225741589739150453090393424063226271167062127000223628785686999799282795143706407082119829140399988180879618548495395684946331608899565543458192773899200054228140747414544792128323269250618482622488195333106891323515989863192944848391405358725993695671970811097285270641251816244586360288952156538400321933146150313939864593445583603568771077260174826348411367609521412133720180359748539721570562669201065857989876521311973120192984729250) + +(my-assert + (+ -12742462236537568498 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747534683311506465130527) + 8711131313747826394504271797986775572294949693272674156076339989631171694968899228610359983845552623710580616605402899155485071497929100432998183040757832449369366844015907530612334721882095163137705867337969942902346066961718232788529860214990099385213558935023241940238638069647809530490438245386869385682221280939688108487754251075630026707075310465788398213293782900699868609660892232563106662995330591906155134237356516622436517046191466823447743155250482328613449506396571170001248589926831956459700467126756876526930443317428628239358666456771112897986098390410773312792390699312960051747521940849269927562029) + +(my-assert + (+ 9991390529516174614 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538345749595968764873879) + 7879872958436992955898278403297937595295396115022400543178444946646147916754852888072481665174663073269556311758611700754643170639645548596647557683044355930340624784190093631808382820554407595007761070026239341594197877214157118335743842022627898879376346092898666610367809537340994845045475091410516226225078052019727419030585524815982151736622865401299588936172760762386183577504972623377661437665668080131418564228642443266935225613702941906491478788336262289516199380144218708241406077806669686589734333554945412904560108150202389909124657090061223183441083590340175629756198442568877659538355740986498281048493) + +(my-assert + (+ 831234034418847630 -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606507809487462642341164) + -744676478858160349467117341859049692149463503380690495147216354303526704924280287782902146026018180364963325847811379182950159627878800024734206345960410146056000392683000433501805629464626281031086102425271022388473812300724085127447081771317912465921636737545371909901577246384446144919253141375367648958387948463576516115079816552636772639965957498569187848459747361493535081532845254971492261148968198806736512864867151355002902241562014241077734122599581732704243705918200179789271894804233542502502119523149682814025979598424744685548054183678652651244898867735764030968089217841214778606506978253428223493534) + +(my-assert + (+ -6996572501442843347 -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314889561060687692538144) + -16567158719848992553565776505785820491834685475229611199353714982570065913508303466008005931649515528390057456882757990896824841386431756898386429000065518724021230756426613661219891419166146764347562529640689229693578574350948436847247856000438153789455857903402883189892697143647998643667467614427922009931545254965075041050860609824086811877108940020349157317276288348430058535959434983921323332907180869396258655826781438419383792024592535415693101119109484610789291889841197827977530804650015884500878613240443324806805475203272442094530735476095374446946252236490708915034012846683015547314896557633189135381491) + +(my-assert + (+ -8920936222630165483 -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973494705119572045938607) + -18738991973681679876688842391791783563249057933653045519186959571392922172943405646958686202208790537612746921398028331540617848217445632123805070077600768524509025758950743971128222843292926773668584735575066246660802064630842300367821042873152766467703905048558085377302000898639290554395913805527529259855535801856020623830262396582180677933562523957295341539162448074423901242873918231922121053192425691524797238343327318801359521456598967984637483081312932069399045363737622797213185099130529375169698811801965974416555301085043300426947769193582129151016159057101028336667142913854943018973503626055794676104090) + +(my-assert + (+ -243510292488206214847646757340020705642 5940577100149745132) + -243510292488206214841706180239870960510) + +(my-assert + (+ 35446324064743728955945058978206455057 -6248622708755929572) + 35446324064743728949696436269450525485) + +(my-assert + (+ -285342226760657637664173494795024413673 -11942737781617905307) + -285342226760657637676116232576642318980) + +(my-assert + (+ 180790435817422032042321866247362452865 12401641959336396832) + 180790435817422032054723508206698849697) + +(my-assert + (+ -179994871947239535956826388240542999950 13573822506399140772) + -179994871947239535943252565734143859178) + +(my-assert + (+ -308198027295905163635866438671452347268 -8790069282378476990) + -308198027295905163644656507953830824258) + +(my-assert + (+ -139324757925833055762410227358605285566 -190622873846936719063564661032771271922) + -329947631772769774825974888391376557488) + +(my-assert + (+ 332866352618304570046318203427223999347 147978646177673305481282943528696833018) + 480844998795977875527601146955920832365) + +(my-assert + (+ -39471620476300923970352914034802271156 28992893610776120142668950821916856486) + -10478726865524803827683963212885414670) + +(my-assert + (+ 274120253734611965146455315763505869288 254675910805265090692978775702306142625) + 528796164539877055839434091465812011913) + +(my-assert + (+ -122086811464559635596206661886176775901 287312583034687582188356355813963609701) + 165225771570127946592149693927786833800) + +(my-assert + (+ 288576174771266329955482943556556984728 -57843540651903655425270706396868707777) + 230732634119362674530212237159688276951) + +(my-assert + (+ -47977736580820486006305788441965482221 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126881113426109906085249657168046936670489) + 984809271313988066640898939725532304075331399066274624928410251834520283291912387208948664716457549646483445981126833135689529085599243351379604971188268) + +(my-assert + (+ 21225484205143479814642328762121362291 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974867770082516862899595554460170417713940) + 11839789093732539327981861490012713257538550745921177905266671749716203131127256902110452504526721633943016923389974888995566722006379410196788932539076231) + +(my-assert + (+ -193095363331703875886398909106293703000 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388168068485304437343508442251302846768269976) + 4389392021031719669078675478621418677903292147307684123866099084349756491860737402449105804868232530632178577388167875389941105639632555852393740474566976) + +(my-assert + (+ -14827657635864183514988182371035598180 -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660185258676369175307019300952192657194576) + -7256545787852407071411458891023580461638051949278710509801472046178301830006724297747051044450550248499056073213660200086334005039490534289134563692792756) + +(my-assert + (+ 54301423175725658626298504084995819705 -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941312995898184903431893212829646845766101) + -13385853291610595576947504757201441006088030688464261540642594993520424631577281077984278942244446266776534612440941258694475009177773266914325561849946396) + +(my-assert + (+ 195114404067053480147948948510253723990 -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176374041758276069255591562198514767063594) + -8373866462448797623435948949281383906369538962237624940506813188612614128993186653340202956656303504523161255703176178927354209015775443613250004513339604) + +(my-assert + (+ -308030589512186791277525017840002670741 -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550454815591457829485684936036414823492160) + -11922204352024596469278978325035646517433105521287613403902396944414655739824695945028308092245747333098422116078042326104667969967224788442970266049942774583538734406057081597034454910987815490244451193242377705191422489528853976486607580169986057592557285271953385769215318545520155212402919465580052078255078759756709086185424029620805084776442744700501748376290562843380642608395240491162047933014854466267084965223593172702334466729933986413870670083326499598274393380692146118979961818816348097032083332695128587696590646086980241100792624502607816103195636761141133903550762846180970016276962461054254826162901) + +(my-assert + (+ -172649878347923210775992373331623646864 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447760919715595005106669653475931803053499) + 22180935775581457002090790736532281654456312526625354262953960635330604551829750571440878712430708012807252279301365732385899228826740712544768476577874129759972563823209525283326887563301081200476495752033290851190327066070873711444930389093339915885090143783170994309089448293499799071372787520776773788274677288230540162485916160484352398851925328125588729604931589867889917097887951581817207079060016091919559509735997493084833476849835444339835031436580214492450731100723026312163752403946315983551266206214298679421644737804098691991631489261658890937663698502561036246447588269837247081895893661102600179406635) + +(my-assert + (+ 17539006966816771902104329685391462527 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507917720426571969997513984360849930719808) + 15609797782337099611892065465036826453911053690739041627254619195700021040383385710184052653282070244915503750549545390475671883312314708978681904377133928647935359080875691628246716591529028104762422990155477702994042953196747769893182153631482194578269859879402160062955490194674372351117284129320011166238130774752386987036267064693133554447596069886693581191241594745541512444806003236372840085705813835001957163976961730871756250344335996073970142337882238844723800849054637237549515249957267772181010402413375667537558243971058326641257721901094391380667244006959028327507935259433538786769416088690535322182335) + +(my-assert + (+ 244901855797156286376563377540855746602 -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760396535767621855642720080219960822554492) + -22138106346578776369849317622304392466030036563754663379976505966920461958652141160336156065177498990718609170201272980114106671808245437660234479124938853665375934080221740523696180221118540569603989748587853373569525751680828044059607889572522502629277877343410298879764820905044284757389006201848194571453112545228115550224254565141563427486518108434758694923122284117299374156393942906293546318323661938734959824887786185558612820887463537294120950912969343488704744978847504513710882720654330147775174336365363311173472002077960424794151168301281665765411704505095008907760151633911824699356343516842419966807890) + +(my-assert + (+ -119403662992279138748600939857239307122 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953732384499190437432898387573320391878853) + 26272999248235953724172008428088697264933069743507017434844709711501131900922919455931092196539942532993887162365511473221418376205773427597933886270411672062672089518774390132453916538404354895529975888201032175628249480896964400801763570333497287321002961557096975786141940970260074557095118887294558700145949117395512768347250531196100831164663613049206690894640391431616112104502483838173255614981302462548882276825096564828583591963617871547373532874400764134244496979962241959713525053686209002866840900623246072884125102845824992994967009109046451949348656842486048332953612980836198158294149786633463152571731) + +(my-assert + (+ 313963939617834410089002930298454269912 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864354021315490712575535559549015858088608) + 23286645405607099799151331553995799851855144387826191186590140820016670502830395945076644578998873585162998873396623634135231418574284200209367505115739462344028303923666952261030907434438322884189133236837089851688275865098623902644385995630973049587854251981548128145516004461191094062488421288607625783540996659060285661398859383778209495884203323937672739376151794507745282074538961033778823733980759695886879886017489555795079194346438911010371103435094677167286870898482214310646392174423422237727456012197253183422715313378603607058548706460095379882633958651034759773864667985255108546985624562479314312358520) + +(my-assert + (+ 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160643580198590073658869 -17993015014355471903) + 2000877973959266893810594143560134441447453310844726478119781029700338468704683515329516333146806175216349912753585564808803731447160625587183575718186966) + +(my-assert + (+ 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942609010590873980143878 15372278140141207703) + 5492930533666246223206322654398877802091439062008700770880939594548305919677404080859141226095489505872709347538974725998600861651942624382869014121351581) + +(my-assert + (+ -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044148223082253439210893 -14793401891248640808) + -13405500833215428652808705089190188280715732437731292502890523313631564795139560159124390691283401484515088713758307366404145018349044163016484144687851701) + +(my-assert + (+ 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149274871082481174186606 8699133332160461067) + 9945195259699924701593703207751086973468898794114625092150620088406276196469184233537941913755508476427888065765634203723512911676149283570215813334647673) + +(my-assert + (+ -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146471920873844686294838 -13079925952361275418) + -1785165974800693006461065312083337532938610906605533088558498259067461510781028452552786542598361030690629530721209490413999022804146485000799797047570256) + +(my-assert + (+ -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311445471793936775767736 -9381557743227419896) + -4861207515430071951958387366611380234482792653010151054346367776006873932152600469133110239669746470475230906073865131648496652783311454853351680003187632) + +(my-assert + (+ -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094956858541960962483734293877093635361160 277811698220276334443479876776376776138) + -6638723469626495957966112633999375479181736600737250559572415894485618850919815869703127084789143821420728194272094679046843740686149290814000317258585022) + +(my-assert + (+ 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240709059499894818265755197559390728940140016 -118940994129137705779355371753506018694) + 1983880417172931934469534542170437296262471214582817006917470485544552211448284732460451903536334682269123998240708940558900689128049418204018975434121322) + +(my-assert + (+ -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454778025302197744540571159656556971614966757 120224841184491944160266976391113485817) + -9354509264984586574958285335910611806441061705184818350015454221731287473282231343722010109181841005578131927454777905077356560048626999389580580501480940) + +(my-assert + (+ 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237448178553189381274150213236222139873594 106674783386899772113212633712093787897) + 4389359421234641412950681847970318834150108533025088077429496538447029921663033978550089607257809597829358374972237554853336576281046263425869934233661491) + +(my-assert + (+ -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448907193562300482925125162731530249763801 192969103435503875767216559494769734726) + -9319417879153488839579936799737117639058244394679644240663244688680826325564084529474537634510092069422987165268448714224458864979049357946172035480029075) + +(my-assert + (+ 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994228143957746922511631911996296931168332 -211230038021470285136061932161632203274) + 1394404616168163951844558734723678125985464491792846741433683801962971891047718103736551854371207400145441134823994016913919725452226495850064135298965058) + +(my-assert + (+ -2935941510094051560788359387128767361559188973149773593522440619832472030019457317998381634585179453958737810428870232715146002408187749944694186205812791 -1221176156661231926164756142840452419679061324806989304452215660535991083923207702827717652226257158321829748247784282139952864899457896871473184473608543) + -4157117666755283486953115529969219781238250297956762897974656280368463113942665020826099286811436612280567558676654514855098867307645646816167370679421334) + +(my-assert + (+ -1338674579024795395027232680327531457830908239605718353094975139226848400289367913459076082700361212506196070727982446232782659114647371030398516119682505 -1298372177520411182435886041880377054374169787570856408996533471838082317927648953576721017727347029007573543972764860712708420553928791798580799809858729) + -2637046756545206577463118722207908512205078027176574762091508611064930718217016867035797100427708241513769614700747306945491079668576162828979315929541234) + +(my-assert + (+ -2072456075229532951804023218627137969798924912365258263779029006567941400203608770518731715660383378937120213112973528605594220795605977413985543331908189 -9744489461776287963808523409593616918248399004543154581056479712028497082820841423941781438667661074968238703192056877665754560746003512076830245760254982) + -11816945537005820915612546628220754888047323916908412844835508718596438483024450194460513154328044453905358916305030406271348781541609489490815789092163171) + +(my-assert + (+ -2570682164188734368809161664810917340861573482754788446510182252413437925852206735928397938304353826925422441004271229738766803460790995673395984247950088 656920705293329551826685120408221577679101260931105312141757138825917579070505267306626244216341686712802796891966598838285570807961966448181138356047523) + -1913761458895404816982476544402695763182472221823683134368425113587520346781701468621771694088012140212619644112304630900481232652829029225214845891902565) + +(my-assert + (+ 7846359203342053693101523606887617345982401999003795257520576318451663998927274759872692123323796450295314377046602880394071105863527900699633560551732837 3683380639347829102597675045842249667669675715600522157867595962635108482512780509393310714588544837398923613138772339053021025559943198965234376657126821) + 11529739842689882795699198652729867013652077714604317415388172281086772481440055269266002837912341287694237990185375219447092131423471099664867937208859658) + +(my-assert + (+ -11692323148567132684205145901751681947225824260005631214936266006610207543813382900867093989444659986091234552140689684476541703112098935301322850961583953 -8534276689564199122569555420819240948691777228327984555753862457592427992599992931175844172478864477440165366128106812103785256271256853749622592560655914) + -20226599838131331806774701322570922895917601488333615770690128464202635536413375832042938161923524463531399918268796496580326959383355789050945443522239867) + +(my-assert + (+ -10734754884168724884333968138739681643742524619139397687680049322697740991391014196697040576174049452737571835233123127815762146577096625434481167057340772 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797378799103456094203126081464905326203083057134061673694975250599375795827437561275156235513192978645909947341297774926450637694325145427434486258223666250272) + 17059878151450238567815178684522345445687980385106446646013863901583786249398194029757376950491550197185231926262467028755342392379269039238766592672298850588065335172902157386017520689203005559576263548017475991638498600879259882041932152385436968424098224966518534467302264172016376096778201462205990822825056602379115848799619564610033123837036507127427054121975400703490855123544706355545059512146550901507159940126280812512339749605195422987937677650572797368064348571925478241747496766586521439314609442534297287570550053098086446170260959538472616804596457209769462541803322821932178568330809051777056608909500) + +(my-assert + (+ 1982582032974021971225071139786536402936929744496433027195224299475980201425925452469321205602618940472354066218156609448199804973454183972974358405933935 -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565757325842468006824235119684861972224857533964558963441079998949499582965764591461900562931342373507763081479989957632695010603500633322408246084430203281475) + -5591374624026484498020036332218412149978824230210339582240360391202660977358546150723165491729699122647688030937226316069237264083850854032732663284717882873051337566653841254365703461654061656817936193716386141166210237666314879751427421825450110467888973152907618520704486700443275358649289847595635931220181024199692771066498714511145489237541761266539978351840438236927937894376002981658065431416811632941197501676956304254109064936038146674412392128883565755343260435032802263894613722185688454597034814467008052803725200106985563165536448093610136770888822609125923739476085562403695659868224273110071797347540) + +(my-assert + (+ 11532228364136654310006206557545352284448588590560137249197311142901246089838098630841794341370689745410654263817911440601934362503092628725755210859171724 -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425483901920822837775032295913486152631638908227467242772081310515646217115760180349854601959031626524004201825198439309850266508687796415478396821644422350208) + -25776236925500995542036591604259749301547568770017466769502569415611770276300787105037848049555500555975152877716727294374436703766730618054071617947449695177320842403963009384468257891933593584757723535299746543328292715942626303315235241470269740287031317322772461137186093930239744879822272349431389779234805703118929710210161489122272898252221025966631463842234537744822906696719691188223105175714602909117904182229960075276443648211003011686250829474364425472369692458701120722289706928607279354459638876682634832113204503315869670342251223760164690255834258791170934621398409664574325293322849671066433563178484) + +(my-assert + (+ -2603756427337798371354526130541868239006085657393372011847827118826669474695402075575479286172808099892726251004549675772420422527946534088483901153485670 -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463663570751134804664228918188923926951933302878771189484614604311920655871182974081898031051411394311700207305532216445616083858025977851570522763537300875989) + -10844269742362409682236511127219508926736627172993604953084481596070757241623728297275447608738915355190715664012379562650777199088096670239050254578284071100042116609747208178716191571268815994455064584659920497876052406993834873124981417288518101426395560764186717660091472734401090302285129741058888303693710456902635092811413971399734306158050053239768185860958896447298052082493590498954512083131068867270078638929796561440903919430094619437872896595720463666174507562142462600272715054468820172308964428582856626452139039482540657669483973606530697567119800100031783220995291856278448505798104611247438454361659) + +(my-assert + (+ -5929887196386997518766568868806997104240129372360669348628384183712406620199102166145939206783172815805659513128544493795329100599632286529420772709366102 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250682015641747568282510036326125505522447591703308661608718100933027549520132308555240654655887041040427813131621391320267698106519650611462269033902177180035) + 24544958491142793859949310604465694574872439331169358241746200808802938771527900616394258199996170862256988647191747967628756772368808644819831481350919782560499270148419601775750932556119448001824346026042068416905254113155445053931789404515589532235225580737103411251232560863878948880220469490014568323308965914171394449781093816607870593225534700167342589927524232815571862258490314644577819742372918446373756857848586825568514909823940075182825283229026250676085754551181284991269757256698525343351573936300939369472548843837113512109453074508716680257867612007472108262775773902777419050979175739613129467813933) + +(my-assert + (+ -8848084327536592532063677611386811805244460767433749071435930786126721080365289638381557872263825830664387392539638767251180242665642373539064690745095464 -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033893238864631158195280554850035949666897861529711006187241710164902350100555999894332438423857208747342184052953230247487231455921360593096823760117493579248) + -15917950175678012281826361248776190984758236997789474333609547749168308439513527143790323694526378056113636462939674273462177686456811495629631337058042159570336251822399402513133598701991665209363955263097315081570618652783181494594400709239428597117944511110842795526862595552977665064029517628515465251448116061875878430407784298951946811321795808932206846491091803276390661869369638950672478828532423383951689632136029256108992610781912267083149156104328033902086948958694787812618527647336478703105990478439936313146095688476821636365183970819981729472573172848440345769886254482636164026235470362824808238674712) + +(my-assert + (+ -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679396721657020438979754 12553426083939460917) + -16314775600714318471451792035636584056297958597339492996728118376578145765736873313518831390349547274517050864260054903974054712997529177834428786007341762649083404743713562157667828894017440065599882523458121037421757904691003094608420565550031561905074671735751685371533975894842331113347413787808917193134135744321547478500861021485075363990553639161661734684228250909589741380076008551020384304303171431833670236949934603973673998262066558668396388979463892768199916011368116729432353268535563246463324517035331079693172060671712718486388759443825620676228470068291448236914050793177812037679384168230936499518837) + +(my-assert + (+ 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269660274683400619225321 11620128128044940816) + 20637030084881771176788188367974505419050866216433677435050410899110162793040751338330447574748263391136356400036001988938659722098883893353523409458775455519257672423829361150611806294256710309281788819450225670112435352092313483086404714074567539245791066202051788986426960935796927738180831688497683293306590464598379493141645539253898709000874685535467854788184424886911457134522632486730390913239660179785071885982403741669161655812015114272497907946919026898579927936299607156006210124954460880383605958519412435713868501997649784658832599101777001703519408664662715322044086646014163774269671894811528664166137) + +(my-assert + (+ -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936248281049628734475702 2380166482232871816) + -9838804688358141062268493389453191808060717708062736103828856866310283812230958467655270667206937622979717683919584610288962829724022506216738929136418489468786902364550847498615864720240589837282441807174290461916292258263929411081218952357662703079709351365960916688275651864441386750529258343003652300629003597744958152243494244227986280506395347894285277364095898602965258114321853474000520432831298793365139040664543928707100657375292032051256485942532600998813627925626928634068613637417702688610315924917761411247617905738119218110678854564441914784262998574445847209847985439514580300936245900883146501603886) + +(my-assert + (+ -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203373153221004361953729 -10586442965055062759) + -30961575335426221869515496362216292453766907587859856766456625722888557357647164641922707199324601608700561081422636642523431947551124957385652791834855425829101761914145137205962610515642614866296480715893528289170482422505734612327038754622917335073993027434927547277037587173529054849390646376806910407207016292483185533697336599641898250465186168797820802225861771331652801064811222606773495565340386327294310913503461903243119204619412324538886439122443769008953829820425376589389335553937319588224864611583436327810214798652896733118881040503785110481197462772022447173744898802421806800203383739663969417016488) + +(my-assert + (+ 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642592954601418753021512 -12227722924075527556) + 8835746018617511846981408800319983340292665114153404569022025834059427359831684523399830234196625160662387716033871154398104436720494608541518837969397374272734698261557358249258503982414578618525420572597611597792132117034895074841909295420434392963714805547538976612884853497014341345150095544449860198192757839489063747595073430612069212219930749783824683135433987509303139260133564905961552149844964215891730262218278214035649706577154652729844092199333026620127958228847111442161350881527928460177763370427262298116900358910460957772350452949782281117704005514462730290063772968929608448642580726878494677493956) + +(my-assert + (+ -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662935026125770444036994 -7349798942312432150) + -5455184800550144006991157215735481579353213544152145628297990102571936052187486515129266239245491863623978659179559754999567936067584384479787934704340911556625153536160778495579370425428019248950494107696016864499055854257192071541354806671987402367524770228296322497224645429524493838356022616251290117624472061673033274133156467148770562815676767117605001434288573911556053311048284534341905722947046607192815465807736361991479044698448267471087552952494477144251510778491315012457514838113324210534577956298926109164909779987221094000880908857594198276812276890284008572664102792405452379662942375924712756469144) + +(my-assert + (+ 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391843039459733925494003066841874935048611 -66646390577667468207341453008390168215) + 27233955893140063612427006607965940109569052437681267421929959186535416115028420267622879017163568256526042146282241931623674996867133390355390677118211537487769195270234259640386625552763891339073878417517169618832945750393661600092643257470064376916337734385887099957095417541169462231630821139075814859604097878094729685589777579267192538715202397220666651307185763054526407234767132218634060693076054116575833737797189157152326979078121760900891899319809724675232853322526718686306470372869701173824664984405178677187081936624687293494821338781534163633206006387449585716391776393069156258025795725388866544880396) + +(my-assert + (+ 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506419828208611247177336492131262918439281 -164048419232636429449474429717211197442) + 15030400024888781078933103028897733817304421960545019199443871381537070197157227994520524631721701055962609956080413517776229513420814407790533237358129529547793422514837651333555776540939235592155512951229106778709351772195248438493792786143040421233061520515971787881798980515709417481015662862327435825812557205663033601853937647320838585333754027488605638576977560072206293290493215523194883494322543800546276353830683084405428005815296131527861252717516620765986589669237487765523936713749717927502645633123584240464131140829496052170285171610845098023517906586134613874506255779789378610747887017701545707241839) + +(my-assert + (+ -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300146993858360430784079225137421074839819 117460076430162201914796277915447781936) + -10227062646189307616073129048534031298512434237226774743330733206156788005874968173984804649812506029813402205606562016228122184161577517837608957023376079537037472977098465137152327215807765130656192272994478964341604278041664840636982572214751638093860605132350960802560601354006634296348422600320863531059118477125143903734159707623839282511184908969206873548650544269932394344952983661665472663102992782521888857016369837211403335306200813816060883478434441858442549261115972947741929087886423170398410216855322384956160289855500229952405068604320121652911887067414460828300029533781930268582164428859505627057883) + +(my-assert + (+ 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707453499030166286828319347894538505334235 -59175168207571178843658955348404514921) + 27989453264793973121573869640708223239762902243991948581280654553806618470632044367386680716040316895884976837122054709584963028986161694425215067648887944710852278135008221491665079705797192389681328802747226171436158375378499411314855257919224316919346771317457123252623293612958336691335423245293660257386649100685560072354549579281852792682734916555498283053758141666658137856828164206947320523255487437004565021167276952652515632644458005291855624829941937578229983628962137595011570216766689546500517528191189928660433013004254032861383790553611840534023221000900694995707394323861958715649475688939190100819314) + +(my-assert + (+ 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851829184120171969918537718488250577987049 -151873924489040812813761508259707631973) + 1178650930337394440162727078866515771626896502845852711186000991913866844090831426017480263676964607121490209778220339316756171449922437605552456088105443130477974682689512446683178356259305893852096425478878588001446154476458310269704392486398646169362313605456233489086567865316333034897433650974160168545492823208575634152241341906068149887959566983066154182855136114289266802474404127414747112706158621650063987662749553991791509795764642256261917497984177610694405881831052199417235241109412927893781778469398975117797578753730248539151297798807326284978255001046995523851677310195682929105723956979990870355076) + +(my-assert + (+ 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821222597665222975816418433744748143385431 -43245950360315656184924888243641533635) + 28233332719950979786871881804755080223325040620170668729385709165879717973040387558150293205758215739710262749733170837042434162049732587908182282319848154049410849721309988807368466228286699721201975848741931128639324322061892706638973259354962358866000024260698793885547287093369940035337370984725857550291339492871017395328145015077506882578124550084937438336881072124376107623716831044079223921566902242543198986921476998895559488862309653154914291349588095330683589871173449191854284433182368052817373384461363574550061788800329400860372148193491004593903732351395815409821179351714862660160233508856504501851796) + +(my-assert + (+ 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830415574905929299482373462584995162798576853564481617711234957058703455021082855018642616999836886763535412642684228990890160568207941504887072856663966242787 1954009743321912552050341299974626734964446274711484506734354360114801426013796892421541915293157994203607853436799102383078659985249097057923578528366737) + 17311283930487575047109155431670372891723312431004343097275158353815289445461275098157423001160013464866170709729134076291306322952612660169010483426086431377525432637844274608988581691477819008626983761905899834444008235608280930166913911248710072733217113558125600345343437000427963292980921009445490627620344145866648036116660335905940809860199697939729919140888034303887423527841395304960072549430314367914315102150378504502158659627719016733307736583749830417528915672621394925512926295137425311818010756329195741691413063569822508868815535038541752179921529616250537665789992543646867926753984130780242494609524) + +(my-assert + (+ 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730196110477118156871579503345757821268248575583821695674912517830056856597644827244194658166928026249459511837772775196175188368236573504643083995409774002567 -5513982495816270388232134254127393284677692173792609278582774509636977743203029647121158805174638642867428501907786521939155900331399058909602425073976766) + 1135960177108146621604027872788612991247811085764456406834564014092038611848908717507207251239454266163702244932570537009884467598603226302482406831131219148530146321028801515381981782506355042255201016953375149829517466449677312249611502599434850555618739830488706171667035140895674806873502543300909514568759918040129665855731078258004983486524477103833885001539135541445685573269814159175744401893663504523858005835387122082112362666991112899837534230326730190596494622340601191271211503693874963897891647903065633935055547219619901624214547537008122851610816644409270867409653249212336242105584174392984700025801) + +(my-assert + (+ -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550976844117943559190671369193871330514473741920389633762695829790016565565261170688485790141638094160105909405353382982945608773290740598479367828342651860878 3451570547959142767282758882796967240086418127970526029661337442068316209707489088420708984628065070358319478649952710478991064476168799556496237099109563) + -30369736932762868789456108597366835061749107555998091727589163626331595118680326568212941898571309672187038272915036839449380083450246957904300051802617002374912724325419651633014408152565340519439718081357147324136023867003917288524338643759680061563616479323818330115572573568245719292922176485298767387601922362893307843067637295955606642841006993776777666041277965868780958830666697755738164183356399977211227424725670822944234275611849032230010745799964550973392547395600047904086434988533547233655502261663236666168452574497249051463199397369432653466095035551085874733030235129782226264429679811332105552751315) + +(my-assert + (+ 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623397410528064697616617917065021866397277409044449982605591256067763430930720398889239414812509701319783809830072841056369381573100589260104551934136733317845 -9461623592584966196513107657889418526847060851423069480904645009418813160370721071067349946095573698635859409908288864150475056170059858850823883834932131) + 24749014370880469345815230363662696846133977441600857690896762642529872426102613384561609594131771018575590861342023688138502403609639138062665279129058939911797019091643704220495944170754490238422880589600838613701783818105188827633578438439212856537589855796204839275633245851474930725845096235668385012500773524750522781174430369067441632028068262240870795850561389232369373523415592833273932285308223863420210049445377497367753786125779044716949754454461623387948904472112650421403957363976978750561983598559536110351422754012117560028168168347462563605746085173970662932767505231098044419200245701110252898385714) + +(my-assert + (+ 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787710331228500533067546198458251241005176280410230146430275074766072259256583499095689284871987010372039977403712023630453400259082684930755893684499232318008 12330599952818018622104330691506128012101935028731995985677032980931398338453806827555760801312052792065671886621851470997557806941112316627790755867100463) + 19070246171469235561279483225919489206942407814032615339351735800304747459507922411906751965555240682457214768298108831815622470433175555196912899313888991765436434867025639919521068437191248198117664398275835972573354886915721765715992151871453808224011999677700078879590132676060988550961950472536029228350169237717222998397029428440792110955380302156159849645211726041489206565536560827557279129751110297078563108009278363910936720061216511798518178957070787722661828453351086168302788942747133188382345258878426260751799053190654921952902516840632788322424832043075598645481924397816889626043072521475255099418471) + +(my-assert + (+ -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027771176714559050403098437684091684851207513969915720607528045624635094984539637789113651579846373399975502788877555747414523231999341294756679330384323996 764238600803843266244444637050072967342049538611688895792923539838804953492110953673720766879606601435939162680753428779068917662740403667549850724878795) + -20895998178036569919774658790651496115060841511658297683195804524712012347695091074325978179977718571444320688167469052862702339462089668992243209990795362064005869602003990235714500149401994013174762139297327430396441552225926368085284222509085197484452650071390132794942944512235132641643003294762547138305644086106533258432786768644384855008506026923783604514268955071498269812887794817192371944269611642901807443894686178438687102834127061425955994253034824027006938113755207136853993047041611883865464431304031711735122084796290031047526835439930812966766798539563626196802318635454314336600891089129479659445201) + +(my-assert + (+ 6243894672855694190803081952962387322599009058758027960092936187687064819462191583137945440936085088260632250436567758576422207449236613172605950116622271404444221039084346501796818945639456207912207604248991842124079786471250102192718092353598850889806607728696519257402580732995770031331187089424192803722612735557735028710899438934171272639518928194764526910590046378401600819132587804143949995694950116915803127294011661411525934100144319021440919928013617766507409909846670172516021888661284467975865076091834094160862228180625536450124272957206172214541444266874056050295270719541605687740822711659847211976891 11877496607682442993105675644902145742318375725225741293060927105303783712520284640625374957608051032540491531573337817824773543104969422017506696018037874641947740606655370938613842356322585858034851150595788166740174872996252792014218946552442572806242471174234462119454014379628228878122072189387777413014452140618318641689597452676091677588204537830401725113931418426919671512011822864583481449136550835952005765386885680701637038206002172218712504732572449659704181315669255320876647592649071711438131711904976335957846353867776093588236311654631696625859173554395714740218099921290128795607292259527492722462071) + 18121391280538137183908757597864533064917384783983769253153863292990848531982476223763320398544136120801123782009905576401195750554206035190112646134660146046391961645739717440410661301962042065947058754844780008864254659467502894206937038906041423696049078902930981376856595112623998909453259278811970216737064876176053670400496891610262950227723466025166252024521464805321272331144410668727431444831500952867808892680897342113162972306146491240153424660586067426211591225515925493392669481310356179413996787996810430118708582048401630038360584611837868840400617821269770790513370640831734483348114971187339934438962) + +(my-assert + (+ -24023960171862805266003610953999097357395283354964456554686635290239019705581779621120391229617494503580661676939681517550103414632840981987397485411400553792707518662609532504246677658012933762605038799352109564432278094548068984563394926376371580465135388578139331334464060067790936072127680597181415407099723844313625277987147283697141407959289588588489162704824409673099509423520008795428217612706997355591985894255450783091681112776112997887084157623388943538145736618168104404283342039105202585543852590302154958791010622670839015475427693311663800177428904406869645066988663292128104453773413982185343111560886 -31939808827732134714870375774276102357277346245583282398423150631754622253109692213928642228787888509211781331649081002266227303203259124984426497846441848502574293640959494009564992092503141598640200823656998243767453860939156780549404892392521391484933772285520949470194562525777116137058001008184603332597820522016200623301007194309404025522056113671560767212894303567191067178003014955596425115379852712737129325098876542459702682095445350281859042779889411325882123213577906096942649941285655935053362468972482748617111598313960198743596285343178242282172686940700127068972627110105953098737923773182254460772630) + -55963768999594939980873986728275199714672629600547738953109785921993641958691471835049033458405383012792443008588762519816330717836100106971823983257842402295281812303569026513811669750516075361245239623009107808199731955487225765112799818768892971950069160863660280804658622593568052209185681605366018739697544366329825901288154478006545433481345702260049929917718713240290576601523023751024642728086850068329115219354327325551383794871558348168943200403278354864027859831746010501225991980390858520597215059274637707408122220984799214219023978654842042459601591347569772135961290402234057552511337755367597572333516) + +(my-assert + (+ 14513652183174940741664411990199277445706189147726874603036586212536012746892966848269748909379750612027025331446918381470766609543142456872580466135425754204680927122749772612276850998180593344389487924747722210296498854143380696064338777945015153982467675141485724865534995199700908286263993697988986805404864429385840512740226775506122190698806967785494289035976495492863456705096841250592980439363856397663738211335801835896091823148249303370609165910779981271035234045185574995335952208702661648744928539539455138167482396767268362221492607154709559716065850417221174683768503217544145599044845325824451589309835 -12814535978730024053359592817368712576084646962861720729844389627130663192435154658607204342320327460695280260731620465435530495952836598646143907272825807563512741964987882356778796849529260646503692618525570185450780889283642116889481314560395290434301143877809550098309214046129802023655714098730144464028249594406616074059558969757405392170810220921023905546104487938441503430332099605473144930508420331873995741851604525954472341693863067199617721032815462094767522339305487934030130207039176659398466616780628644572276059410087128533031562978399689702766028716401176531098447698206272762966470643604141938670152) + 1699116204444916688304819172830564869621542184865153873192196585405349554457812189662544567059423151331745070715297916035236113590305858226436558862599946641168185157761890255498054148651332697885795306222152024845717964859738579174857463384619863548166531263676174767225781153571106262608279599258842341376614834979224438680667805748716798527996746864470383489872007554421953274764741645119835508855436065789742469484197309941619481454386236170991444877964519176267711705880087061305822001663484989346461922758826493595206337357181233688461044176309870013299821700819998152670055519337872836078374682220309650639683) + +(my-assert + (+ 11356479761814008572465147431830778885327227506593483181241437802252618729479905490826767363633131720717461693888023278837835457496021519184903984385091047829540007466025527592005114414671285638168997562037691602144751434208304408870143450743278437854754504713023422097017723330207792526222436928747286558205279330508360438281011315147578105966454344087225699378388309094140949428028313539634103047841948634832398526343605363013644180832752120081735152285507591096001749463421326282317713079361827765412853023201330345752038722069405404812511739634687282327711258974520622248165974215116400638833123609666501349513623 -2451734542868054449539778460457497703609327132304922810342762480808881050209276687756391911546806187586640918078231508181876445466503459873508196878629364924241891220686182517218825181707207808769770392864734466652524094735160185556148554260517746279303022469784592528209667497664672945900929888144529727881050106027775707933311860110618130543481573815538047460723253898548348335762406437618625388229555824532715231231491787570056329865617082709588903922431713098922691537317839185452018617461891748518176708607861270770493263960554805373552348256747200291438630960804647686832667981625018361034564086859426490014044) + 8904745218945954122925368971373281181717900374288560370898675321443737679270628803070375452086325533130820775809791770655959012029518059311395787506461682905298116245339345074786289232964077829399227169172957135492227339473144223313994896482760691575451482243238829568808055832543119580321507040602756830324229224480584730347699455036959975422972770271687651917665055195592601092265907102015477659612392810299683295112113575443587850967135037372146248363075877997079057926103487096865694461899936016894676314593469074981545458108850599438959391377940082036272628013715974561333306233491382277798559522807074859499579) + +(my-assert + (+ -1814184401790217165873937825605141478060935014868566665644215718762341535891730598045990231798382966074312671040257824056876679135909008140059087311700216658095793352051583071432744886316274989901835606602224927350560604355249919901932382803472476702792978322468747380191775778902733911968522382089332819162367884984027854067607561808704316828316820133400099093450636968732151876570835173932998599031643640476109466728761033062776578175554441947411139184426213290292577467587355369954997241091769769542810051228504545831588488726789173405585678190671534386784806998695797717346491308862362775748058331375692317599945 15466182953987394334491149436346080039471412309427279110582769586053943302670765125931570041904640518032832554998553018838321871748542118021556398569294085708441934948186080236498081517178574839977996802813431873543309853609838200338534343580791382510179184571852290959723696010410340740895530535423959476873857191548113125728667781953125153120447892632916574768078583174099545013854248664119997703948998871566374080719541931440495888606776561795893839624084254684939434035018741535261951124673664746010067859317726891535170781460914710499572006592206360512398012457295755926986236618644330364227754380084585899275327) + 13651998552197177168617211610740938561410477294558712444938553867291601766779034527885579810106257551958519883958295194781445192612633109881497311257593869050346141596134497165065336630862299850076161196211206946192749249254588280436601960777318905807386206249383543579531920231507606828927008153334626657711489306564085271661060220144420836292131072499516475674627946205367393137283413490186999104917355231090264613990780898377719310431222119848482700439658041394646856567431386165306953883581894976467257808089222345703582292734125537093986328401534826125613205458599958209639745309781967588479696048708893581675382) + +(my-assert + (+ -27127130599753372624001250456405972983012981437652156246797208697430661165612459362971759027335854588888552031022264244768883843080959804690580574272908031271224646245152017114094021048441971097191444782106551075175878815012595015584723250801765859461211934306789890718268168352614164589637346918581658850565274510502652089457352942736418509881708568727739912127781455473660768550022762222130489047215089836402367851853412705556570667960548570630054608024914653686223423908494006675057953013815512203710764854485332282975729323105427143207127239069826750682633272289409910001698385240596625059970587393681128674617278 5719655139276246085992066702308194672442413085748146924567717361937179810269300239821879673460959112727066470468217892213025828988023367028158410455624528688729907493639908638553730770145274142147983721694721139760883483821883267129411125364089207412089113869427479340283853501026803387874124668123626271531796990801822527792189514551888019206405597994403243358155410088320317141454525417323186389587327532772638942220300149829241141659063128602316305332848477566686425551944956989370838072872906293845914921103561360871571846865478762953536949621421094416539099628942010528483544062050170673327754206501716239719529) + -21407475460477126538009183754097778310570568351904009322229491335493481355343159123149879353874895476161485560554046352555858014092936437662422163817283502582494738751512108475540290278296696955043461060411829935414995331190711748455312125437676652049122820437362411377984314851587361201763222250458032579033477519700829561665163428184530490675302970733336668769626045385340451408568236804807302657627762303629728909633112555727329526301485442027738302692066176119536998356549049685687114940942605909864849933381770922104157476239948380253590289448405656266094172660467899473214841178546454386642833187179412434897749) + +;; ---- Test von - --- + +(my-assert + (- 3872339191937382556 13437882608410293981) + -9565543416472911425) + +(my-assert + (- 12702320881720530101 13823645380834800545) + -1121324499114270444) + +(my-assert + (- 10222969257152373972 -3454292165863475982) + 13677261423015849954) + +(my-assert + (- 591233951053628288 -17639978232337836611) + 18231212183391464899) + +(my-assert + (- -7878405903223218778 9050739027069287469) + -16929144930292506247) + +(my-assert + (- 11347120771894057376 8443917396834074370) + 2903203375059983006) + +(my-assert + (- 7831959259127703467 -257470007821066702597399141202130667973) + 257470007821066702605231100461258371440) + +(my-assert + (- 1092406341647857980 -325710450166845666190895573961860069495) + 325710450166845666191987980303507927475) + +(my-assert + (- -4220606126689357919 73461013742902296577411907972196819778) + -73461013742902296581632514098886177697) + +(my-assert + (- -5112059189225304080 334306213789148650102245018234146620793) + -334306213789148650107357077423371924873) + +(my-assert + (- 3093346224554776175 -204967241927023874963787190016588249299) + 204967241927023874966880536241143025474) + +(my-assert + (- -5735747638156472357 -3881750746805128137401544408305666047) + 3881750746805128131665796770149193690) + +(my-assert + (- 17639095392510638323 13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131453861285495087665017) + -13312205908441007415860933757605397223142073616822325142416364932887680287063250296996056787873086490231950036662943632990219865746131436222190102577026694) + +(my-assert + (- 16304056910692545233 1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417465834928609990708982) + -1463591032326743052350022746892396184459320617971409440301562638996633667625451301419074212369365394140737678584830314878769698416417449530871699298163749) + +(my-assert + (- -10347586523508777315 12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173691528917744363375331) + -12614325304787850623826535169596975975360455924114817820074336137897280818245940873677389644701038550150832199897314137414727161192173701876504267872152646) + +(my-assert + (- 16875252323587344863 -10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527788318592431794213674) + 10230183557696638447600885112945653217398839137450096120772416948425622105048400944465287395231588821521217980407867153259741079758527805193844755381558537) + +(my-assert + (- 8574302739232756920 2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503759011790017443478716) + -2945205250727759066959418729185252318153395797902208079569164623770839848878181416073351760975066439564334127158302281471631001294503750437487278210721796) + +(my-assert + (- -17657597319577965851 -470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715357800461845632614015) + 470389901349206124503884936612357721199915776516939967013182926735009022045917047211666512521578494339222795740836335004070464944715340142864526054648164) + +(my-assert + (- 11472336850218354926 16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290339231792790773612376) + -16764018932433717867649699977474298016589762238077229911249331402108995850754999065988360217500238643747316139204767820295123085026049273617874157749889925712672510963712964034497935503076689670786498045302562704435768723916334451317158760704743066709581593570757498670622547878516907127632802801541072452593999435195637193819500375063696114131057474475407791672955417184592088612921927282233762919112197264895445408873539746256555444555901857369535350160665235184955438709679669964546134487688796078142789125799020704969226557493354453298489954288702387159956161243151013189140749021799388406290327759455940555257450) + +(my-assert + (- 12682607562584942903 32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884157735553718792115929) + -32133619583510009354538204193505267426986629771080807813988708187761849276650847958886764459302043799013813125903744946349479743277662066609741649009023451783267511140245797235200413941774959851628239089013586399425314412329003636059313583335807925401822165199322334470452126484173417518861322963430951772895619791799137157183662289329901964728384697377777905235894234370773419160283767144177627084271804319157013765325677633945370597318765372346484383325176768117059688792498687750479618961541872574768601477738410497806623403054372221338126223825515939164627992974469102910882915893925327931884145052946156207173026) + +(my-assert + (- 14621880654476679971 -10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579655168106377696154728) + 10075923784619510279100488003620810539888599376089081798647754628017452762406215094511315867213396543200861274584884759429891242650999761503100661310915213260386281412125687376866399124849043409890009033179987278297335571911640353059036551139958369871790768643514550179661619387008678118363266091945225880595898524898713646458647465935791224159084684209727153050053537752111696883536364966526666445737103854446009305531519860527938394412863332757413309423156200192973778629503534709731073637828912608835085933003410694216843775182940057891552358942312728978810053715387504707194992816961400377579669789987032172834699) + +(my-assert + (- -3220156644655019630 -8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543667539444686619670713) + 8347829670073174550775641165362740628312221836466572623516708794243074870361401136762432100726575330214254748615114820602945887237367461962207075265579588481261313345359877816874924645801358760718027997416917747796144940020489321523749233377708490614979453376328244189926517907474704635785063100359787580409065317918203485474119227673185211436285930586838616288721370975925191964611302275354365110550116042403226844820172448647475637867255305805337047967053177320593337377763657329816935516961201488840745892529800883680912275812320160312651894919502389242002380151562481051684439333368396132543664319288041964651083) + +(my-assert + (- 11628988978410243120 21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111014116286675587727714) + -21091260149209133824278525560739673446778991946138130571540201996950100883736332286627324787663044982195445635023357027423513202277912840570399895946346028843517588470258087913846945044832851780108963206182331994065720076983528527849542421619745503796476103034657238118665288185878258232226731582201217795631247916614224227701409259346052937919425072595891571572960468193421257458185693656090215937518204243652916583730260295885562094977775951577484951577581277292356830523013216949489797535362720471761788697932265967910160407593278848113303674799017334692501935041730808945554336564957621028111002487297697177484594) + +(my-assert + (- -15960716439913426281 18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592227795474197104696127) + -18799211173341989380260980155501104944815245973352765317821146163884181375747259542484535639646490774929026134833947975785613727050541297797675705933339289016115326958150660323801621778641184271728990164666383865587422591755046779736996211052149338115836473967202556153668963815595875844414662034458693455631979862997316049580586739835122770408911308146605671192538040301857163633538268589024651373766021087864982140201615461513687698136663128896835597598904095187715456109340116329587986878167776146023396961265667934659006280575496363066974484893764810659481361856335795455814679851690737943592243756190637018122408) + +(my-assert + (- -181065640455671431985325539445069267017 14120143334024043377) + -181065640455671431999445682779093310394) + +(my-assert + (- -91295299684959299024846233061686623774 6891102275697080803) + -91295299684959299031737335337383704577) + +(my-assert + (- -252582289949155881579950873916766853744 883304029266526072) + -252582289949155881580834177946033379816) + +(my-assert + (- -10104159950635417603045689770006558103 17251490913777465304) + -10104159950635417620297180683784023407) + +(my-assert + (- 288463495341489091297108607960869684860 -16376960611483226267) + 288463495341489091313485568572352911127) + +(my-assert + (- 204661965092367792468062569536290631004 7774991291341524479) + 204661965092367792460287578244949106525) + +(my-assert + (- 174559967167400201536723778015754014369 168183438971818617783400303174116396891) + 6376528195581583753323474841637617478) + +(my-assert + (- -253300708624436983509156598368557395374 -77166863757693227553099778725240875400) + -176133844866743755956056819643316519974) + +(my-assert + (- -38587765028356074196061530813295290944 5999161273284748726648331130480323187) + -44586926301640822922709861943775614131) + +(my-assert + (- -236400856885875891058508662756360145662 222191413471626205952456600591947275777) + -458592270357502097010965263348307421439) + +(my-assert + (- 212937903940173587742882129816769611096 336470165768472077447806282475185249734) + -123532261828298489704924152658415638638) + +(my-assert + (- -264812595676159375893264580577855253845 -247068943830535581577267897204259299723) + -17743651845623794315996683373595954122) + +(my-assert + (- -1725732715479127274526681751197327660 -2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500508887739763323997191435566266331339917) + 2279805492899538651574406423954277869507456204136276822451602661149698386520868702017367409743272511010382761246500507162007047844869916908884515134012257) + +(my-assert + (- -220007189346579184019349894240059989979 9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517057595815179415042385175627374957565803) + -9116030813176547770422918633286023943039811682891023288884273747820892639481842291616424036020927750322528731882517277603004525994226404525521615017555782) + +(my-assert + (- 139683266109784685815165642637380856544 5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108688202931002414214353708335212597807345) + -5782493350903499652295971390391981928106911831248674750993968151944332845911526084530951283012280786005612601970108548519664892629528538542692575216950801) + +(my-assert + (- 239160165978290709841254489756277328273 5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464958986304380141364542178714472948085275) + -5152132850125501873897264811465207492706871561577273155117982457627773151595716641409297120994045059130053034927464719826138401850654700924224716670757002) + +(my-assert + (- 315772704643232632782106484978382006176 -3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184616218582046814434719444842678248982224) + 3689252327480456512393153800679864208480329729627292260734151097785848947569336194072922395859496552999163037466184931991286690047067501551327656630988400) + +(my-assert + (- 82735713197488344149642668226610301853 -12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097816492579684543651922277865558518876774) + 12473025194535761005577066561696471986140205263843017221991729197337093872383371857001077050460827652296473928714097899228292882031996071920533785129178627) + +(my-assert + (- 63472235942371758467270296983419551089 -7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656218937984504828452980698439495961392749596) + 7866520408163137968600317959735552406794938230345293650627055135268307695389903092041438746530663083967329111232451176014649873249349534808700483360707382397988918594143264031213181385790969271527978925616276399184489007642142996251807222768397530946779296600805549276528669432847672215219943599871223372831999133812100481632278022608906065923652981249057846548868473376683960144009223047416366697876553049362242497225174860431577034875737250719899362881567590934060155436179316063810148362442197071642183371654740845983314705249832168923202400873364289483910868432511677656219001456740770824739165709792944812300685) + +(my-assert + (- -284018520801241078671538235859630240269 -5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682401429552174530714298081464588450842581) + 5529748211779294240854894683633173443789067073881249229985499707296461959655918837051490512357840133495603640185675483847478587849599477020706893805485599954539589062532211767295361120129440287144117406526027552427750375526095104163474774446716012360038076376952619723549765229763943818011605991300849052030142173100367582906381575666628005795818339029350398340616624791399526643991489247585213423174803853961438830286737553181353007081438503238779644371968004083452645077716952159339978836669723137339898471600546912430030276920763475622536295311290657163861398519747560279682117411031373289635626543228728820602312) + +(my-assert + (- -171812101820192353275910956459431262142 11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870235074909890698574792562001595287630131) + -11401673303315394031728944442295528921842441448377692701102691446500671963119794838260543877466107345474902885032629120622020177051592733148817057943390167845763358795044702079370835841331467130719834250134674578757640577473495192331790176510774020541399177011446664359866582351045889299070080989390219063301859447807907203943168891690028442190793548699886572720360741686677780644932612683647303776634496172481504075784427704287335805355801794320914944330891519283383694196486986108936857630373759865062862204149003789919218681050221366182434949855054760827976853645027544605870406887011710890928068472958054718892273) + +(my-assert + (- -243638660221338112796448050030955119997 -32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408826226326879491415484319411662301650468948) + 32214383478080953899491069562585164652288236626686985994647827422262342469970423345510055643470262764747630363450204055220886177681745412924556264758690138113272748656941509018308925555317383307928766093730384151056027828368474245304944063213926492719166086055718735381341569379006804236876950175122702350552198046290567043195716369691666842524594399597143281611765509174168738392889075290806378316647736667077047013214732267367344808724905727602402784621437141760604478301412768904784950365257469208085143467704875589485635570084387755189599791857576855454112556762755762408825982688219270077371522963612270695348951) + +(my-assert + (- -126332081511349770866908261827634312283 31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799809203410103682003414364238243553515261) + -31497387372874133218238910173378055967910722258532087598053588964599898753455370244114881403020152175272452951858324158004662566613339529101292284073176382818309096142522412043073218657587031893636358434796164444941535757484360125937835242214199979245499374972029624710574236962978707708765065292759037309958875006017588240959790355958632745299212449602934380927677385974488564420550408281673927387615657765312151272852486266800510090872812376232597458154951925709496664568906509814364388823105469855516803225244972466742963619633076158367569109107733990828830121948130235858799935535491615031774281272500071187827544) + +(my-assert + (- 219979452670016849533060110266815720199 3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063325766995908926108582896362623757323811) + -3900115048441644499033281842448985956665866771934663536385503692700586024397767816761943054115584011069129310718114010862034970648115172218305599786238607524420973404711138276011261135403209178420948996472570042497859127324157786975578751148348046315727383390370594954695454631662061021971027739429505825056455676233533511412589936865597034183410893428831818716136282201523804692574965779771140320669492229416601369453681528301333865290947482219850340728455965391492610516639151652595539203632139883064874286555941718154489936421274731413286355640404192677546692090304496817063105787543238909259049836252356941603612) + +(my-assert + (- 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493643522748210870974797 -1855792162818946202) + 585873325961105129055557280004608765382109855007674169500308242261038324959928764512890600512016613154122762798104714052579267789493645378540373689920999) + +(my-assert + (- -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396746566100575461602162 18009081534399282710) + -3026050092505200332789765255096964033685859497096213532090644235603419347590512426830117415222669642053441336442247132403948783838396764575182109860884872) + +(my-assert + (- -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580214088920441698992069 -4827559068742614723) + -11124638695599888462310706699308855434715251048597328942409434888923094027849143412724699165971400546471660924330688750607774759764580209261361372956377346) + +(my-assert + (- 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693871318067007752043113 17597810481352184048) + 4950293428090696283711882613183655723616682297360442241017758383241177602498881186549809051670562038601658285833496694108818253845693853720256526399859065) + +(my-assert + (- -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778775472609306735864748 -3892174127829225880) + -5733769947958740467479139247420201065087494801172241127791526686385518674532830661413722661802560247463032020003355494614502034002778771580435178906638868) + +(my-assert + (- 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676743031117653237018365 -12861394200627120797) + 8320894458193427045187598554188178307429755504967209344418448624882517461814957461249858674758807195827056824653471934409067429988676755892511853864139162) + +(my-assert + (- 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971731015312020770945603825344926844435936044 236396022362585261770052671762207864597) + 13033402737450594044106258936169013897237368708138118260402180886096095497725071502601849887805439844083105685971730778915998408360342055292255082228071447) + +(my-assert + (- 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903680828294561265828775791256812588754280222 -276673555533799047589626400978981416789) + 12170667278114656173974716189098171384426379753661081475485441559687661443127166543908925678856145097632475832903681104968116799627823380883213567735697011) + +(my-assert + (- -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565826229169313660087149542130819663319659 -157671440495648010763311068579191828684) + -12755594876262399860618168642932232021734362385933348033134635580177924615701078617214764415318471507488803810365565668557728818012076386231062240471490975) + +(my-assert + (- 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053785280430612875488847226724390758938740 54361107931665215623681874454167019934) + 8664063140780163008577373335591938905735059211566906376953760862047748343846207426667781783874718320339071949903053730919322681210273223544849936591918806) + +(my-assert + (- 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942391817131531474661895913650810587431606 -50508350367572393968128467319633674717) + 3699576825118349347309026261327541749454660339251578894574483235547605815416603169143590292164644149607672871236942442325481899047055864042118130221106323) + +(my-assert + (- 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306794511840379704578900504784165956486985 170502882789371639987361620116696459267) + 5626548453644136572409808769267055618695663227750732922630041368983808478347120771651822300668480671524976882745306624008957590332938913143164049260027718) + +(my-assert + (- -10859007735074693411217019392659638207496329895257318665547454149984863458541990037760564769787816800806064437172810158051442267508476778676439633382657890 -7558060977666720080449823996328496253877735754811271086853901493753796001778345391546991917892931500169890406340928835457635973812901681485438886367096185) + -3300946757407973330767195396331141953618594140446047578693552656231067456763644646213572851894885300636174030831881322593806293695575097191000747015561705) + +(my-assert + (- 9842028993407961669727766131360795288615020071102475108883839785397865740828387076847892646234215787999498419839351470775471313077046438080666908734795616 8259939762466350877481193620364896193464602165170783019804380181692322874550956777598992104871440502758410340359413403619753571535498118388286469082729503) + 1582089230941610792246572510995899095150417905931692089079459603705542866277430299248900541362775285241088079479938067155717741541548319692380439652066113) + +(my-assert + (- 3122315115429970622394662815735050825423438028108957393747131991771456957037829402044934484343765915727397519247940959221091465331254497476137639859816450 10737995515603450913722681305571315249864367824351372254572936648132763616823019940208526402092654554035074813865303483747097673960803093638463005072804384) + -7615680400173480291328018489836264424440929796242414860825804656361306659785190538163591917748888638307677294617362524526006208629548596162325365212987934) + +(my-assert + (- 11618335890332522671268040181306950825004789685088262996478365976802329054158653675768163009290064139158450983598701977173152384425333441365287895694522192 -13130287008197231017935223399369698658354829835061356451363818961959486828237111511740029441613108087354987794332115218978284937263725126538295501305403242) + 24748622898529753689203263580676649483359619520149619447842184938761815882395765187508192450903172226513438777930817196151437321689058567903583396999925434) + +(my-assert + (- -4829477140897377009195646150061276059814366801005389903693533021027427566117360765323647260121062827801190746646296803957067548167571028717513392985791293 10716557117391614298810040587314742187092120526669273567183969821384063434473189717686678450880765426943205955814024872764413373364846268902370055526485180) + -15546034258288991308005686737376018246906487327674663470877502842411491000590550483010325711001828254744396702460321676721480921532417297619883448512276473) + +(my-assert + (- 1560421244904974852620371975782132605421448226892487453928759432083522187778803424020804578027100625536441377609275030418285893555753560195716001014786650 -11797558308994912054526619290334311429749533070145154703018977152548370444659962978040151671210413666186432921816690953994784423526183449271023503069393845) + 13357979553899886907146991266116444035170981297037642156947736584631892632438766402060956249237514291722874299425965984413070317081937009466739504084180495) + +(my-assert + (- -7701347923966912534344428538744620884561375267012102797292378941649984539207353887059064943586048644516121387166836442084007442716291792933061162738380376 5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642478870844024835907350391770605391526921411004262446196112836319091260967898895009427182171643279100998182191816962677328417390867021108292139204864164048286) + -5290969389374230541016502448421359606252744677802288901830045825873182202718418905866055323957065013553046698199939002159982374580735362593037515863844280108947533575824820196689891621498006303535207762625068798755031433921940066544809959896067184147997503827988613858484669349726945188167613248195147619673963531690938913245110754715059472477991342216448470339490385593605806518967792963339193162830698488489270925945408227996742278697477358272529028932771642486572191948802819884736199144136147805972379529458298910128698032910952438102363314241236586865149642698313204129513770501398309737400085072266026902428662) + +(my-assert + (- 9733743430220591762422540139212426729307515492818443460852332805653889275463385649305231919846970974905736816260992940027028218064265519723018527155353151 -29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453255593120138178690189726206775893096279000909079330468718593887702543025737308336025198677457129910473491269839827087491228569718246503140134413881896746751) + 29407855293830047984154639411082591337348779678279017647951764366455421210163494489475996514661359700145916243499452007595041420522019751347743105082745321262372977262641488359297167392118038994384136863563032667040671405618315550876997904307423736276844997706938133936081058323434935833614475654922773162140266784233792639117145232791514703532554345086520312281500696798706889025860427142771458666376271994240028586899592254884476941388776984078337603148583453265326863568399281952148746915105523008308424572148912179446220508196915012771721674503909376976881448397006656088080431255597936310768659857432409052099902) + +(my-assert + (- -276731217243271862683214238489380950428392903790808046630969592255272629537001990355375434170910931115552132394269672247616298060929507021008951190291387 100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150102261744547461816282538319258966892339056695718919291240188920586288417893106046698069355647145603908383687239983874164793005765733782432717429040621674) + -100289083769237476480554074865040988004216167545459907207847010762380733541100608695693297149249375537088329431700364201275915507683345148401600569951338052791424407090330310974243070931256108167365334162914085216447196038922091547331474328250886730614683299908003398886233860613008266913065047699535081030427106800418656336608005860846045905149012346378286475449307630537665901621055008855374148058291266835796203075976592585729940879567246284967856356337849150378992961790733678965752557748347842767449599509727337871158512841561047430108037053444789818056535023935819634253546412409303826663289453726380230913061) + +(my-assert + (- 8505070389896098095621766692413480203366379968950158493268895987250690600795955783113900096527432416791184386061684833478921638080978014176210898461637606 -16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728677459134022062202283647690649100602260948409511070624300011106517649666031530376191755817891213910847547809248990517666613043010292627100428536737652546738) + 16410711613672171332126342754193842244915477287016327757357714698751777287458963458682349581881560880814595167244857846847668988374679430572782121021084683986742283012573569894084166107235597351093334125816075658348307113218478800035703971671113417712009419861470917307849916674203301497919242668373376352901312309673053175315189945730756118172940886476343290174961420986113367531057713782438374928471960914578818951372282574754612716278516397754222547513576728685964204411958300379269457341514082464314789480020782793280002504900356632326331974869717987741343264338993635052202500091964648373605114604747636114184344) + +(my-assert + (- -12618010259109779267590315037969998053964054382853891516547435925972388025118492931596200697357628900783311183940584302426381939302632641549019984810957030 -30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476306906983993748299291616038887011943864441807818857508443930272872365334665976442185494702520760793786640113779099219233665607521784524244604432396247693263) + 30500906828861638007306362171210132987300359439962044769219457463653547834815716264412200930088623097530758080891972640000479943534665059199377729854850415258341537838023739964147532129877743393965857370995558748807382396090020006195649251292012405690725917389684473999400905751109361754679152179983739269026226054012963756892488872262522587481931950410504651253101938824790285623805566521723062029033001745636445860437154344665483641408727637784045030118212476294288973734638520024025723849041945810477753436003616927382836946392946640857949253898501823403164885856802595158634931239225582481891603055412411436736233) + +(my-assert + (- 793528769616879938852241178439496352527042950647521648629732169156958768358523029837406526207126598190786120139491813624819360632811627576064199559812277 -7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323018004882611048769247228828875493680284766874334247375868318795940759082324831733175858991629741478124633015067484305547002438816473086042218906532116413) + 7357484069649002655190557040768215614708659708788999334802985986235721030962928900092675952032143512196279092521450986819067071570862007086586132687661085824939677603953832219860573980632016025218580608321648907608385784471745482257672314890331358256478273312255285010343369949412955387472116587504557483184506548209831317705115523967163525846685455369176657510129844566195941925821733027993620517287411895496215426174909366458092382652675628195464969405904518323811533652227928708099470007314990032811809824981769024498050965097717850683354763013265517836868076315419135206976119171821799449284713618283106091928690) + +(my-assert + (- 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554199017672360091721648 9164115638960783470) + 30958566711373255787092081401292877738974978442987704470984765018293851031728996862405055424093249924047528792113585028592262445810946419909807061004531455817427671594281537965628880611732831524185850161910304038646992464838306728350704966234151134620041799373762432970330864023007632010865749239024802839173884778578927209741320635135275002489733299806669933393428518104197594560039136096527206600870299327752296492029012993590212340409989598323540081430189567580333356380487749078595746626408529223195894600223743978246922817054226858311823994547784553612982586322603593335538875728113115443554189853556721130938178) + +(my-assert + (- -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769237154904791412049964 16928681651977808800) + -22540807692474380279530794404584230073523360203115293035869063366926380719566516089428840111682263403627532047214106171892715667227836310498366393991106231487046533598391969789120283294510723096483520917309134391072655861112766764278247568027435618337967113341863713181603534251049249873125130781073437913954718595729437608729446837417196899902194261111827656247095442897532040935029872731410799530408713850806239149348700486268275019296069828199088780767614008685960242354118969741283398882689239770114582524756296906388861630890288875920861344939520380841337675934551587994259348267613541166769254083586443389858764) + +(my-assert + (- -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289916823063616573634058 -10755560408227106818) + -5403850875869356031749551669837202919756114555261706106905659104903792701565965475066159243529680606410723686422444947172225540145977333194008702465610630608545009270872541652430806931212184915840724378685979865349848151917650322286497417985248678815214889868576385900691591784772762893647315325310416150353725001943778473686980157692817497562783521120544549784746647104651038037129984152623720529803205580894126664077380391379306511348324442512538418658728022685805514196592544294177914956734669359073791151050869328577099869772182315103156047405800398706114122356939316464974680113324979723289906067503208346527240) + +(my-assert + (- 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427134042574317487793 -126159569916621842) + 16201587974698660164372991183566748501003872177894450603471850345714117528335101264234127789041855420954511595895378320972957964222386731614839583078498685801156670229700092209313747849610762975747730086443186821337319452128253859293962343891549207804191088925361935683615063225197130192492652062735684739784075955094308092423304262201429421582566117390598395895220976999990205945523225411701169301910362640419341608407294018105959688929256136725564385243617240412649023368133778798063226772467915584333795357813292935080009919284755332034998122912861893282865727947810588086156919649131720183722427260202144234109635) + +(my-assert + (- -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617308447853505824391099 13449070890444925581) + -9976758107386398142455037422077809088581080675608340830198269021688955930541332630075972471934165382030070969307731206728197760190279942894255740733209190331510591013089699837164445642396864912572863786290237335963836376543389815671640509582958465164874961381137096877288362944469137669502842448492172241151419831252572392809173900377271652074261706120638052379886108764460001026094198502028776365675088466580595870167840105746912975236851293882732079317535103041585285239081516202482201377111734010788198635874359396626004300532752450289119192633850562141516671742961938277967783337559307443617321896924396269316680) + +(my-assert + (- -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414447893892341891463988 4431555062692055371) + -8570952518585194406209873586517687582701183275108243979199329595605282282125006489076327154374449108678257552384372919282846744626955206382078850958298637157198962032090439427286914716782317030245513658212430127586764421559372214829010306717557679285031617989735914399954286846456953917915955558448774972943731602144914068097214910567329340361564904028964471241318105967747431610163083002382821902859161510204381788262611298660559327478615315484763561786397041779926288206767156863141140852268323253657685018587945456372648431446464389004257999049529945532453598011773843788498650935959375182414452325447404583519359) + +(my-assert + (- 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637382775371488874447622330992324750207465 329466253508616383200261654231797136951) + 4117976000917214601143188578494558474138167055110060832594841842655428229500889876131794484851166401425675703592388271925904534237338595998991043982676292549088043959446082382516734793718348862105938692342851330680670593768890094290655852108130945387988863730762717733881418314989528719379494082656897158942547008663543153236129762264443358316776532465284014215413819415615612452225913947961681691310132286840303081453109375175436902292224029179426794714036524361081174901146731799945483243427138748119832116750910126386838614645397770107366925613473924955965862778639046707637053309117980258064422069338092953070514) + +(my-assert + (- 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708269410828528742743794495302359380494607 126536164564464424337714470705049463978) + 28857935543824608075326348244201981931023939250259142606733822094071772153858420201297951828741003977413353359215638528196235956061529059419904405354390715114239219947402126760298132539402386106279333968395498788354937020337343839325588433318100331044091923709732742795159387846354148919054314582749477292946200912006940503778924320301062789466388997936618573519744795661160190636101768486096961991215006236190655062992372061052426455063703038765465688361316141792840153608145888307784845264037109867657483109819380082597605481013612040648149090345778910883349230476481347645708142874663964278319456780831654331030629) + +(my-assert + (- 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199731850712255885395479903525322397561293553 -169494171680584797187706369710105239124) + 3146199586408378667812619157270468624370984629500707476575291934586478540055436137993431548830607708293475788354970610669452058906009873485175438772484599603993015239438297747261356407887781450787482447252615210880612867127689283653562498484594955015919746443263740095372831444793239911996227663006098501180972347442107190398034048225264564325230296723559400768342331039755765597288518435463475921534765025262262798267314969774604439319964638461636007229819888743218820584570149249791727508891676067767073852694327748467914037392778283816153183422263956621516748627574334199732020206427565980277091231692107666532677) + +(my-assert + (- -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152307499446188262820058714564165108542508 -26845770031559702758807696432929071597) + -17024716654716744558842421452239026542281806678754026383430912733874686056449261218428541803113383766132449624540209841726047308927951820311213785345168358108138304716549475322223600292513384537980742126687035576531330089447100646214364923043445903103768701639992829171572718403272488931980504461938688955457870904289239032709146514866818331202329982821151580491257491540240579366183525075936339515949345815704583685855315810611089822402567649542290589282153225725537026309623090382054078872576985425957096858376112688308214148412270019118710904983829984589093557307164347051152280653676156703117299906867732179470911) + +(my-assert + (- -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789655406716271370732069643455590690035701 -321447426701397438572265325285879998363) + -20875354448001792153279041347864644172439177882677780548397567327274288309764204295853633150227327732322157811413794613378828291977852467550695289535036337326494269114787031260705326469002279939986228049380615128280814933748700667874022724707001736732724010699175779382411342385842744973636495738468838244099596215421975861650998954057316519632062827510021706536194961332185926551767127180751211669386674770139039516623606727799489291663572125587356845055646322930167536458093283930082765496058330805117442824718962237069840252138957395570892073194575112213410604881673785921789333959289569973293497378130304810037338) + +(my-assert + (- -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955696690287600957842671916189752415855520 132223863177855649509430852484092802671) + -6750548706930727136186675393752693335334383613941059024795513640678178119089262068912855951615043660442324823673049951182143778744824110223137384940032268718291241014850714197673735719784663896993460156686600813524168487673234842233781654493200950459723884918456280719440022930492599128086690014332139955274261568563155723011697763382009890186816226119314994799655369791620499988988986590903148198659095740939986627235565633349906453726759224441608018598520571182643709143072528030332708598472074166415467718451869993686505339408706320298338691467040585228617379086727764240955828914150778813492181347042236508658191) + +(my-assert + (- 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912743446197670724757690108283368934769626461285961947257397454619164856011847736479229692086038931510067165282571276049292116713101550911614590774659556899356 -6114512833799784097991148713266650451765474382378581896952003894922931741133332233338460555227243451198289670274036744955599177213449957470212981501678055) + 15737797902964168014939893286340956118635524170934156177365242966267432695262586636031957242055461736359478270642576860414422844075672388559647477705484719667060463718865742735598799928335211410004369240278699196301127699945374217439676378682879115442203681638050752745036508637214733712716867800216723838016099572951915042604603457902610639317648800296497583507890473114507231814851908526534709496988648572353272479026750068932474334642929727977996779536604912749560710504524541788099432082201420078226760344325839294406623059778943588869811463030546594158753518363572241550086037072312278764361572060987641058577411) + +(my-assert + (- -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912449969621455596132708975438173455827361542712483153981422051943690720556013580161324856788091093465837542336129629269227369781823515673967591796132853515009 3321161637038961370471515250185392889390643163295535903347391615170504064647249127732639364682803744773593849851778894972403397573953564801884397178069327) + -26633154627863501044020127597209297142657179797586777727331879111280843451446814109347357601013807189824906954310855123313836812409388745541128842840054310853220032505914307470215180950497357091093642400638925719682307925365402618310180378684705799724964274776149984064608716300479893889145492885897234574442542501896696821902329473018442082678749291668341477914681413039643187020003425962922948452894682558162414623956491734656939841377698702802567258906642912453290783092635094079446953423641220250933355646449517325399335305891060078227410452589427455776269582315929979481048122342185221089627532393680530031584336) + +(my-assert + (- 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741918196732794332451120218658490129307932187658010681746557120172585093207839141764683325214902696969028472942954863209641597556494684135445935915485525220911 204625459185084436546676461283890328511903949966691877662249903659689934813784661695047569885195881142676761876303280806728760511429260843727967794322777) + 27668394897866653012794531261739800318882766882548843941974485394983434533400277607364280566269718161470415771058329222680901477416257843578362127708934184467195154000133252468684612556324066063725677629160438683034201285122508880444372096430021219637788794365539396242345208611990491721052691567092029622640533057073151980959055665792776356282961971341363712186503783566960850166774438868528799819047163739437906559674823146932668464230936946321915236658512741917992107335147366683671982028845417603675754060715054679457922681433517904327980021630167332811773147330266192986906360790827734172706185092187517730898134) + +(my-assert + (- 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321037694842089561504643350632756961329867761604760788760440497535611072991056505806805291706178639395690245460397975614715123591611301423752799666149495108752 994321141213369910357526037382331323092462599623554452705525887587326552002660849455542761618020243106424015447778226642816634338781654345001677083881111) + 18944451653774463090918576081661764936021793389045063662102219434278236461286997354190032851092512146937346521704215170240383659165117708716738711782597164244188741818096207452074083439983059414271417130274747048227795964884943105011205424198661201055104372863019759130697888820715782179466491256695453118035286889359217448004524564796840711987314064158194625731263591557915838970249677548534895064545467992194029425250039951132361639559343536937119283951538321036700520948348134732993106719578998544669142161165205987792009723485664504503145955836163417021375447139036382527836488480774976962642098454664472411227641) + +(my-assert + (- -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316157215551931810740200836725504693738229444336470213883741520460842708733150362983831267583568258736572295448486287825894301201018490203520738439038977754991 -7402949251688548738762242219263594861535354011996392637087346760786292549376145193266590582054224293289596877537643409310483743293801574030358189880866069) + -25075128489482657321316021943980016828761861550379828525731288423212311433274066958090940464803020097932875912251380196071686918459370667428905844496548191635733867314315152547202859654044591981512687559437417616479425752991419002108503390319869665933757684966460526631533822984311725217788657567199485442486045019468844265484117570385156844404625735176559901986920712550964238722824122000259551821135404274194791706113272773768366572120227974096419295159271316149812602680122191462074483285430143367908982458217491104433114081922440600986838638000992986204512279005851608750182484990717275196401946708080849096888922) + +(my-assert + (- -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264269215878469013316796620921077244799814690434355127994011220041638393750697699141479399553359747084811371804524490919966410379714725200415331414459870271869 -9247155945465656153397925559476432992975541781462281935278489123804934847762489500833913193183733932905776020790478662969835879365116238125565077744775032) + -26509487378481600038412836495388065888781507388737194948728047318975269277448073484403390476243134990463394380967295356958474984927721196047241216945988250219075749832868804186657201899994373052648345989716938779173325348547767647529160988985542438998030764420175306438858518207072038513664360905985908879070216069156102379349899544471658754952888660878997691670566078979940005195987259493512159628198906090101827331841914429358969184839073862821059400943312264259968722523547660643222995517768366821714892573665712075941552514588815849936651978565640166563350878466028503700441303440543835360084177205849382125496837) + +(my-assert + (- -17010604274474750006607667808593883725990508452473783283717890546525148212376267233909567638545898628257361383837671935903199638230375408397752251127816717091041943873728526445398525706450929660366518707254053655364610471112296477865068960744948010561798109833411657930112293904378353445961131058136287425064317621271289456901138718557297733713446119244533144377470099270824020439428168481914824420861176457152299497728390918971852021025089592998997807574907789524112450146545688385954763667980124432645276563626082835790429598328230426471161191074551543308732791287559033843466623138171520961684959997180979203053477 -17319079025684619178510812811805110270463447771889107440996086020812918555191263705580533644731591929176480040622705607552852994906782176254877135818109655911838591767583157894999741648979817400330572419476101372927546509769818404491634583907246692993992514876697330603464497645633398167129555001859772111887143352351860130929715392173452396253437927361301990735683539169040916027268831202732178553152351117118606495416985612909248422655861312689027789401950549626643389790516560291620711705848717875304929186131258525831197192620523261738944873398924939726689336762464320190834794155527335576391767307110012289717973) + 308474751209869171903145003211226544472939319415324157278195474287770342814996471670966006185693300919118656785033671649653356676406767857124884690292938820796647893854631449601215942528887739964053712222047717562936038657521926626565623162298682432194405043285672673352203741255044721168423943723484686822825731080570674028576673616154662539991808116768846358213439898216895587840662720817354132291174659966306997688594693937396401630771719690029981827042760102530939643970871905665948037868593442659652622505175690040767594292292835267783682324373396417956545474905286347368171017355814614706807309929033086664496) + +(my-assert + (- -28362352496476494327713713233021518136860402239251781438945998574753662942796270292818595738100959519541952077905620088422871490191217157269435052965329201030095268586136492980900212955645939325800541690754639292707053269767151001292253701853012092829784482071789669480438026889625605099744553642207773753943711175375843649210118677569597324789367425691177169929576236753018329085700397911235750600921874606148324025962628852167093806152864269874177214562322576097931390470469397118268354868919899638376323751276807304678316688836173746719723312665764603485606350244811113608471530958617108833879194264695174468397461 -4081062111675377984305281082755054920741203741273067094307824323728798665450292976016160959354997082250970415737745853292134965575242789548167162064123232363464302136338349828801951197252612093077640695564825095503535921549690447893467349156939791370286866987224201115453216606688305427702274940837032716124925028835914047967887674858015919302546781010326385758988488478290741665427521820112231266659657169118374988259423444686317389869729817643396097464874333968181509317307320406521221309011946212308190273531009796563611621389720223920155554879800901239072885025170342349379379336047732368458185953903872634982504) + -24281290384801116343408432150266463216119198497978714344638174251024864277345977316802434778745962437290981662167874235130736524615974367721267890901205968666630966449798143152098261758393327232722900995189814197203517348217460553398786352696072301459497615084565468364984810282937299672042278701370741037818786146539929601242231002711581405486820644680850784170587748274727587420272876091123519334262217437029949037703205407480776416283134452230781117097448242129749881153162076711747133559907953426068133477745797508114705067446453522799567757785963702246533465219640771259092151622569376465421008310791301833414957) + +(my-assert + (- 10367142604728811799331249565431331488313655422005202933702176605382043644320209814639311439871418581341534233560256605231366966869093495784665834232350567124110194965198962966795893926025854156729633358240069116588609932539289897499402463770167927610848388138020589286461244557962368497723086593344721146859584146431437967506007518396464517349944129896971137720357645026281243138165214047233258394590454775153944241555543594427555914116439316287902470043292624597940465373006598913770411505099332700167695871387948271302951230983772351549087620538875967635100644404345317626621438913980275970160864401622986870735123 -13323117602411502623386235160326625769048477819798659261203460002048250420188223753407093545503703207645050883770850457071863684414849353264890601744588860687970804808452855795406182324143949747985869939791374195222513169904228914579995165180964917538177994190229733465224857616114628815752065632238207474599531507602861647623695058640735949593381112671690796335596142010430124683781417828023076027476816068202219709673411776556090962187853799456968290579708094595903778622705850818245685205707447012659247018940946510378371952655457988959551256869060428488498330109152756599450626641948447980234503249330875085656261) + 23690260207140314422717484725757957257362133241803862194905636607430294064508433568046404985375121788986585117331107062303230651283942849049556435976939427812080999773651818762202076250169803904715503298031443311811123102443518812079397628951132845149026382328250322751686102174076997313475152225582928621459115654034299615129702577037200466943325242568661934055953787036711367821946631875256334422067270843356163951228955370983646876304293115744870760623000719193844243995712449732016096710806779712826942890328894781681323183639230340508638877407936396123598974513498074226072065555928723950395367650953861956391384) + +(my-assert + (- -25321281404861286799950777949097462701962113587443565138655462269365151737118518315058035825695270231347401755128007072923189452859397209062457461602335603630181865680063451525170253746137368267674863889514153713728814272332433431604233690200451816570240227260445028630591376891139306370205846627093813889699170594185178241812081296510140572331372738998993116117098817936927692238682202717231675283209016857095739468507690090676681400453024293870135659990528969837132054786661560150259115734877162158755858653364070279937027014730947342216816307219127474721622123875699701715404820384545693058511056735799834754890692 -15870257059811626693754498423136372480069134596343998984549199283973854570508228359295418026089909378687774627821225399931314225867711515277913855368473873536462450935842786002269065816311054834857109074848803122494252885020527074586145467185882674518032764708782999568002770206995683800833252068328835778749976046128872525287656002968632147457840467536682726059599593635219947081138082647985895437016641903078766878782632503812736486529143041369932038649270950453231711525943737962179463585338023463992816994328519710963267459007592689204838965317062070771191372220277256094361390952025057574056586665509010902583686) + -9451024345049660106196279525961090221892978991099566154106262985391297166610289955762617799605360852659627127306781672991875226991685693784543606233861730093719414744220665522901187929826313432817754814665350591234561387311906357018088223014569142052207462551662029062588606684143622569372594558764978110949194548056305716524425293541508424873532271462310390057499224301707745157544120069245779846192374954016972589725057586863944913923881252500203621341258019383900343260717822188079652149539138694763041659035550568973759555723354653011977341902065403950430751655422445621043429432520635484454470070290823852307006) + +(my-assert + (- -10064759312484387184876313010284016458560725440641239737323234767636591183611201479885347260175161165340917225306019885202675573016295152797559983194160634880140345743489989007821872426587698574795394887035658449467358615185057180305109018898637903449135520486663185036663238956537895356325733583128141439025002140924158670346599492383552938312402521066705186885506193758499006001382444818328802338159713646715901977137011576113434170842422373328479181457354927400927267448788528116619711184792932525071391797130057189079431487557270366699175956757661488296856660145077706273571985222726397848614141194988258117115194 -3689074607001776735792882994440038588887963294487080609346609068733026224735369468180206799966728461935654851527895876039403151156669223687679382665269013769686991783531091821265184956524448064027733731862929686596729449196238312997460578818232100254940830907672953344544031914926653652310468671685310332327057444910423081752028857828828473637496272809899061573593874011995802487442092326045415689987885712749026491545159340468151000027397821404233369034594141219014219707193746581364791219277489927025992135462852894714639406751538919395016165215641239054420028872350709704191189169571752512626755385998505584006855) + -6375684705482610449083430015843977869672762146154159127976625698903564958875832011705140460208432703405262373778124009163272421859625929109880600528891621110453353959958897186556687470063250510767661155172728762870629165988818867307648440080405803194194689578990231692119207041611241704015264911442831106697944696013735588594570634554724464674906248256806125311912319746503203513940352492283386648171827933966875485591852235645283170815024551924245812422760786181913047741594781535254919965515442598045399661667204294364792080805731447304159791542020249242436631272726996569380796053154645335987385808989752533108339) + +(my-assert + (- -4621513851362114851854472268081584822344822740665629177305004335694395719163541988311496405455186973857145245414214464449674464879082042971313025249648887349614046805778335573547862191522938924075560443632614665169520240664970180760364771373836023824195690134618554368845612471858027311791638881380352344527105480173917778084361560336490212845414303819150625355111300877737042696291233444311426721588476948565949641149735838580313236869041013210454558557732497012037162735013212361842433337324577522358968152852532145622765032318936569346015498130151789662274686368870963891262060214274101000058555635785833724062234 20283847238128227963042817384468009365120280641032764409860857066215336820785816567924217697745867082423864450685360959383940995237907453126362378908108545669654749698030305432673477271848544313029448526561606175059997663752601262173667861202924953502866611309434183496911206954880840674239880495147451496219568787221129244201657487090244435562896841733049066453539864301122516559479757096183362477594406691085946787803323712522074578611082872627361465163804239673539339633332349145205596371287028267780080937728455742966681547897652607170788637996317683436193829274172400558140357237480809582038468874094877651383053) + -24905361089490342814897289652549594187465103381698393587165861401909732539949358556235714103201054056281009696099575423833615460116989496097675404157757433019268796503808641006221339463371483237105008970194220840229517904417571442934032632576760977327062301444052737865756819426738867986031519376527803840746674267395047022286019047426734648408311145552199691808651165178859559255770990540494789199182883639651896428953059551102387815480123885837816023721536736685576502368345561507048029708611605790139049090580987888589446580216589176516804136126469473098468515643043364449402417451754910582097024509880711375445287) + +;; ---- Test von * --- + +(my-assert + (* -1412797070596191471 -15492755620416346417) + 21888119755986895161222137392796809407) + +(my-assert + (* 16686841096925954110 1491135775021813104) + 24882345731730524499708005167300657440) + +(my-assert + (* 13262412958100188045 -18379071970155621919) + -243750842254847872704698616507823758355) + +(my-assert + (* 889503034794263569 -16600674457216690894) + -14766350309325860687849239111838240686) + +(my-assert + (* 3148165694020236318 -11771070679825280729) + -37057280896113409834434531491271315822) + +(my-assert + (* -4443818546267181727 -12001052312087213799) + 53330498839175802532024121011435050873) + +(my-assert + (* 8305259347214213793 -229351169208067535459370186456659711595) + -1904820941859811670566233132773219565154696335396051029835) + +(my-assert + (* -18273334758510166901 290047155020180552782039318570071650475) + -5300128759437251944808204783222405076790289915320785927975) + +(my-assert + (* -703280433697652940 91110448009482115063492795153459771021) + -64076195390496041906141380919369524419358692517527451740) + +(my-assert + (* 15279634596127882146 -220998726467849290098339792307263567896) + -3376779786638352686104608499923871317791563686466157184816) + +(my-assert + (* -4472497681184076830 325612942672822430032905460436166528379) + -1456303131067722058341139305566346079551678140995111358570) + +(my-assert + (* -6180420673489141029 -161157288800853703711204405567379740552) + 996019839388256252540244286609069684717518686623358308008) + +(my-assert + (* 14044956603588468379 10163190459901171254101452124764637970005230126310661589196828892266636678427020930101076689732526935899135126391465178494895371156141265424428405590113790) + 142741568963316278148132287599703960511135825069792278910440475692913696263448088587778211787403889397993501704943449376875999977937418748662459138952952917221024170426846410) + +(my-assert + (* 2133283347509865817 10577710515843519541178984366353275630877942729579274295972091544607384358263130633386329706527832990861547566574369528634541156662300858851752195966167381) + 22565253698228972909216255630133478029433774404794962869038558824053350969301054394347471181756471783852326407546652836376109109470959746153989521923555764579738243072315277) + +(my-assert + (* 7812722507014599311 -5055959518947106416800910724733658104378582281318226107212861190073091017493970778425583956006925004399967175604321778956828368132273155364830637407968648) + -39500808728232764770485117356353304373275127104839804121600969932458363071148383405901570717732548020267052999198017578112731079638156026910705662052515278317807704170401528) + +(my-assert + (* -17560801708050275829 9842515227842383346577123873881045824143545509071137371075701856197189100217561683579562062872293951325890789283651221922663521213150065638405410634222129) + -172842458224605375239887212582262805312641302639067963604956593404910080268476692854082531021580381176489626536608405283010496488558204787140272050713264572452317265305619941) + +(my-assert + (* 16743386830114877156 7347065846171565625701636575261347705942035850951855454324853850791855951431141198155170102434274509450315416946729031216385536668189501958761688618635668) + 123014765528775807847206414290825117502032199391400884957413813554539073118943905948723779020186281150198999824020769031248882909461419778092564985979904308229718874140000208) + +(my-assert + (* 12697192948029671719 -11416780209809507417142822520376617951137069007568339428552592261458272400645205700952156716454820410468812274673183389934216970221062627926131479014990611) + -144961061169197993494569769162151457365959287966302572862364500950127981616038900865036521107816831702945678695331078399461327412574397914795455218447174498277798426197230309) + +(my-assert + (* 17005139720743105479 -29990519259587469661876904501488342396062731024702923152492275204626478246142153608222329335341363164148761307659972897552084842238285026253664841395295138667328930482145590159132144957515157474957872335043653264146346772142483721767458961320947069718037828473530001033848282453826154763424789967441239969918856795769965946388666154136004597297855416503729657013008165049478441197537144135384444157408972370236442813734429031404855591324183846423588871065272526864866155918285777640819778251612915859290336548446745308788013234099839998683451658620461972798204104633072664604846231692505409653434538208644416538994256) + -509992970306921990341332390474393215554862069848994183152714032617297815196921655222705396130464246880845576204295466273071779248718654338767559016551390771145212884412809612574391658668778295682412755916528976282396155832617323980694289208942491001345059122414240884660276842648466533488559879226195446807748573906940273568334343093922652142252689341425941673567630236228358747411926991658260241924294146562230425295426217833820067881064577380516936937782688004146531121831211284735538742160763820814174631414364095096099434285754767091040812242751724012532803037860394426031234340719537172735695313262283511554154662650333168783128624) + +(my-assert + (* -15877530153400521290 27863984127681242643954505352420303514833683768731313003271701952957204538094398204984051331105594788039352443762851136101330385230866919393696564428736685568762923746771275677491379334452751710169529933675128178840986001684425353245791752781476028565228371147542431713985092322787978914276414008774443194161599919167210582437024618824616489802661351916633993681556274980075051797120207655478780052593534285265078265845445633803877185868676955831374479850746658711791169579387317321983669227930929736238215792068273805543745311609083833407544342964285215427999724272264458975101474080574470499647168865409458531868592) + -442411248181132450919255517905812929771246981404050821923231762557171158858876183536414772404562764742655092127161703706239729646027465795612501446223663310668879007072125975886873343449629108246953385822769744013416908613100114754904323190537317463286500657291202287742354250227377164455244103312266617146454847578457073139633297517170508179596166314955134347046515455569689877574427319658085169791949003021426613961459610227430636932814700361914589752207776142403364490846294795496119883683491811246550808038342285518518431538295199537270236275774546666026424361019715280652576803278928827199810150387207105149968313623040090578323680) + +(my-assert + (* -14162897687527555611 -23016403916121951319848021112075986869602408568431399211927062304968548663313037929311574133954267816204873252195499803324830278637331653769648377216095499136975244697758388851688873078022850203685120154634090802825656419418077380419130449990938627982123188424119187922828250625318327074513352279785514062876718714640725789938556578327139793467832731546881422469843509318627826856881082450937188956068348931459011923844607158528494902828851692203126881727638511348944908726926619613375594042390434147948508706733126737304560579515324106834237197081860910657003346633962662773394999353766192391746258372744063777808796) + 325978973798843759388794644178802841408656469654887121096165875654577046313115917671847505813174070119516580105483409446057747653173640660143855580491229746795572929387698247460831363721394707501497262525550824977473864621747159715947297817600227665840640555029633517390896890601028716769035575763283168066843141870124768085499453574902575378368669494153555135898430469356384416638130459557518713454927909937610851489821263029886989981438507377741962130296498574556444168140838201069779040087521405032426995145166201901368032136008107323350679784004016321425234898132080844200202007395427054392280809376612533414505539109579739614954356) + +(my-assert + (* 10844738523441551664 13010289169828379103330191247192587220592807931898339555723704078985668371901953113936581573750666143303899278973814509164982887504269303358034042953769514772858989849512527461308415676004712388964136857232374888643347097138114199889581495448978914022318770898259317738823514820591042321773469959130347470144905381758960436645008051488666423115693738341045851119808222048272924385188356021826450267608127588500233526688704136268009202730309974485584784539415807259862449203760469406037505772435323036790641520939576046423540699016607317147689982042035523118533555744274806239272109508745089640043900389441390176681340) + 141093184161152226992592021994885140117836445291515772908453669279294934817987511015413332614094493905560980363483549300117114491702466085602279965168041684355125886388302948336158133555051817733078300668260616983283027038746214728386770752826764135491650323133831923154477800324207350667020747545837613879364064704092093040155243919335078139087599906324684688427176309081290932504214653249366429592335409761783188358003723753633106574740731573467850133547164922532633897844647383889253777956821171583261238607289172489135768839436605233457738153233579088224808850428203888700116300637190661108848906846940291749737998056247719674749760) + +(my-assert + (* -16402132873169057380 8202725117980211375579199554494319645475746305836527475507064811368616698686329266053570766100878145903342129595869654087772486685252653587846560946850102095086896668181099435964053041678323706849735936082196618754721606824996486473796843333331029865501790248862590712245450877098960007272754260813822886287008295409755783478345202299352891066800825979067590290793893933819913530599309037639082839491869155044147367415785329077864525961799400923643936705317921900308490987828345313709179960659814100113658528990241758360711799009722683007157350272749544178688961738222930753008443755881419398858537860612954576778456) + -134542187307192759584182063854799850608007421111316277594191532129597970622559949723743396309231347084450105499455916612009290113746722460358793168839937004812915757145655285798961178877391232945062437277255128401572171216279188126380587081673725314534095093062983435026047851041796084651601813918099532876684901239903769891552275465470747567830660442193995685219383258617057944010709906130655663966913354414611799232001438943448374556294933488875450563987147224709383408815994320229340710143082135667640802837699940654151297907451396297241124380508001357553893328703788960812706653503939250831164194874527033594779746890593262611805280) + +(my-assert + (* -12094905083549825231 -7303327854122277566083382629094740392048421584433028903125893639493993705575691832165314461496849401726460344615713884253150283931509897329926825128629833541892164122168618243719393446304446866677253728405617434021389128710195093788280203239300086905325641224801020413858421914412156234316517981228056539721130386645649016559425091470643854813419057026759188125291655398451427686659900364573485593902992038773538760663063071699966278379037038361219424927031644750173900916227834573604566165762753650347331082640552394430002401423199016978155236550541225512734287851807727860645247391524620773399994302380387697957581) + 88333057189654571362020288527489792875655269960629008914349561689924145109953656394378545526256758871407020025766992398117775520525507898420898102744530402370720932219749861094609497366188371774072368034971851022164946370916317410415503705484491514312339956381120953283812334833067601825812118392757289250628861166579446800637104996060739031010579056633535166403083327528575504427815713481850979373113173151813491831551023902022537957860211597622343157802805275942920911544696695931809085743355666792408029743911424760065578742910735408262758198787195579745280191859776661700139596074108035867940154338953640690242795671183308201526211) + +(my-assert + (* -81618231044418675360403541307856740187 9751573706924018395) + -795906195858402819552264165081526765614024708979523739865) + +(my-assert + (* -167600745660011044249531125104202473984 -12960244919927910377) + 2172146712516287908809731894157839567367040369214826131968) + +(my-assert + (* 90306383312124738690336097936949488486 156109477991590792) + 14097682358164298866835386043901377722456291173827620912) + +(my-assert + (* 126202800261728727198105694812165074067 -17404362862588500316) + -2196479330029905727399352310201914876903532806486592905172) + +(my-assert + (* -80093647977875266525946940496137725572 -9499399805878278852) + 760841584053111508349403804472960020663660465509267203344) + +(my-assert + (* 304052889577333477963637861956318521374 7233536405885618691) + 2199377646072361697737485358722028853038393128548297401434) + +(my-assert + (* -124787646062877233829165925777950698937 -125798384154373172164515376683173327013) + 15698084237137783175768362160964949930745617334715009097620154581879012485181) + +(my-assert + (* 259623502197082370239517374851053110076 307089583871541575627915295134832918432) + 79727673252974285068387698133566605944659309374400074880377824560177225320832) + +(my-assert + (* -245358177397026033963771466683003477163 -285087883756432161967673595037725276963) + 69948643556453419103498093570621669430956866597291662675473644085666220495969) + +(my-assert + (* 46731711386059374483493216849082745840 -216522280665540473581476116002923812173) + -10118456728713381305690589407461434638634240429858378588644634276171257110320) + +(my-assert + (* -301422430661955757433852743238845048860 -737194742467573013847855072675441356) + 222207031145790358162820429948896977201848379524899474475604149595884654160) + +(my-assert + (* 109781582310220385246795023904554278713 -273317662617851276579672019029762858338) + -30005245475518685175699313262818315773200953201653075289648004177366787958994) + +(my-assert + (* -312236719893391897821327608828679767006 -661158307192284418474080017860142217763949256471548515134335997907628404839044913830388499435166012788226998900468665646723366842553747501004752506346280) + 206437901167986463762021023207669068873036145952740267172145693855475451354717023377588805030022300923600718715029262618794758202955817341818233889201852381575043965927328029955969846754837680) + +(my-assert + (* -134379788461141842858846278268259347105 -5535479645589936472405910397299739073641612836770238183712206042659632410776896398062277742229906915852933418684231779996404071421767274180368154310128427) + 743856583805332082970350662728998610690268824090148728726850517499798631519601137183443104910590855501252539324674812560702657332874686395923181633958702249128106139207076314713649515720653835) + +(my-assert + (* 278271843790644800793473851247546123375 -3845690285506025443856370771250487683891303505653819308540635173436088084480277686684743918745832832765066355874381847690771330587033980524869033600561589) + -1070147326395532917564114389205677334125034378502074943828571411806344559859053091006175486397820822872698474899835730026158782698085673635033947150554253148685482702599776833910878579880042875) + +(my-assert + (* 22345490710865165412267189692679994671 -13168094845644809414256057134926669929759930873747535851687323456073141938879368460977723280750841588750507348317544461824280674332488497533955177541413394) + -294247541053147552931885013427268298282376074124656716577088212043667912662239091316191145352314750820026626159649861330384837204227899202392764926604802655267738710003310052268554637728023374) + +(my-assert + (* -223445051950608517881717261787296926498 -2609806601119499724524852022247741111662431776874117401343811680374867931883996125145979162937751368655661775097445043144114599069842524778189198926688379) + 583148371568187658089071213924575304457465978545376486297236105670932990897420147110485946155066725440999079357995678147717407410446012970360780626554347417807723098476525833332400212113766742) + +(my-assert + (* 12604140228725912459681435851589379433 10671266866958584640992033560488052420339425977492420594983497264069815016478448589306666811246532193922229713077112601565462530332258877522384022088660628) + 134502144009302626262781543880199144227907004673612064586081220538754991037447647926963488301214672345398823354945333417956344119228084327815583754032364976497975702972112644238248704660063924) + +(my-assert + (* -221289678591114384943252477126208006780 20020996887149770966522122735176842174467884990518978494604707026520269232864200848420530223248762875769520715632742683760311747174524709550334825291720803698613541109690224185041740294906022358446325921538593105347423518731748623037078340006459454656405997570119591344894717789372844612253617591807770017562530034107842444403952657949565007792107071767260484233194674888488789619319597151367813735192433631007526015463229060702510632792171187339118004038505860316305860704455466207113207893106982258864355430481457640304138738182009363353560090082819036973601710432437342931523433079941958203038050750205966472435692) + -4430439966231074415853738608900692925851705818190624801199561884242897308817127146763274284287396980593383317678766559004881552228480591814939402896201244425805503258878061459604511214900528594870260206969839682573246490602076070316760182753341371682323914671418233629420599310422437691170629449435494697829163966912842611408632129590129483811802031178053300073562716917597174161526976287351465154825036851645956354853960835948518860624747958440181683978083391663149733813297698623499283645627889274004656942800842013709298338912226207338477579862672216831422765369078886850523202897989792734789430796029206661261129141144642117177625405158700499049991760) + +(my-assert + (* 180785619668676509441152734583033930295 -11909038209406834057075682058438206007134213485822042209417443270921391661498900475635417780140585878716264253792335317341527677051828500780153492153490249297998660274828986996948999762620400587091118252205695562417522111840305140989214300921122857271717052213225664738544344394774362885331856170636862181712515248810239601812262573113794334115259873527539564296101166439562124016438281173202196876398090029995104489712272260608848551754611421227761245487365953257890749115194455096508613617028024932657498899001119282498614739316599704645009607294747043489655424155986912576002393048535846081096337705941547991821928) + -2152982852345560218506186041143281789706715672110278207735389192913214838321097754496849942223194392302524369156102301165660674797665128931611291246607346536492650554391248756408556789391955568308599431054809433808337036546281323840555452571430884302696950144068129601527530304907460164571704857360215834011779559395577299313379666503707563751314135201994045874159291100986903645360754621200008830207429980872071814202801994486961737459218017354210479544121100423399040398021780750351097082070296255480707530391964970754186799748521538525274241709676878827522138880241734356460339681718690408853314007343934035505873192699052380699509877559455199604508760) + +(my-assert + (* -196121729286794751535600080816329923561 31755463535476988506639447113088283661031267977524968610501132544098607201258848456920865390506381665724254592728643925608893982794532243733117636645689751360224314774452374503339856173343683819017479955914451013484169313685311530532055735999039466721411777061709328450052490025363788971916050033904534189719389237878257877112162843506491071470067738867693853480174965212750301808781573369342701195147083717623066339671595077736036738235636996351642097684597005928843274525502529735435418805821748637387888409663397547514467435322454217015563134545731593492200855670248739786405074231658957946422903165662016649229286) + -6227936422881500100190187768375947805694946596622670066116457374856427496311253030141271922822486386675428302332027411428470488965226898801659352566022706152307022438261392466548357753526474097246042956052374187605144719189465046544498482461077851578811186829094445089366592317045580466302238653533114619908864036973070346979261546801894831273337217021756025770590122176562027129481076270727248949609326868225755958667670279949371399535144788247565199415296122873444199709788941984099349149684384486618280260678252604631431089580057102263617056951788273430713908768738965854953667135156866028646584137788146112300214498814212865170902491169332389942607446) + +(my-assert + (* -149247491509558553673630984739524508601 -9241905448313719916485289537122695595500213295294799660583133638026091750542612875183284894676615989153030773719811347110864468582634048542108726080717551794580656021381515769591713295631818532114918070215760259364277583650102628486861397602958930509695263902920994329409932518607260720657755504091822028630927071374796474717671220452208310602827254296323761245420486376569048549643478954846020045263141546849795367522490793641049509748005893155533480849922847230018411440739584477452313387881413141538766185123978087175960946255649923135634987656065468774634483495944248865774633962770893338531522570776854773975281) + 1379331204929344851843348280532786532350930013132149419346606977890849868537539899667631713548510207947097949976792337278764045110931774279794402312944786743575421497528669859045492875676005849752425421867514661792129580445000023570590786705609341859529483054902802038173138834528021423393677908655442991197348183257271932188161681770513283703502340499171444058119260228931558784004778969491586252899270869275893402714040693571919281494643765571068045362364213060063345212881008657925426024923296369533374671614852576576041747836643356665301762059898161073609265572267138950725010661453917338098901465732991316661901878681888138048552901254914604845891881) + +(my-assert + (* -246070233154436622785727814428081917418 29761582253452470642591719346200231425423204062498655510037025199574178834762931489817919404889920159374886981199608181795387339523762458361385170203883094308920011218315748466148953320570427838912637152446837553950810011344492780712558515815917745810385725989241835877316836808088478276603934260581342710503593237081689944686263274319354100341139245512159619947319496638082702549196795236216458749363904150768879765280332386830831409591769966706351022328535490587838695167807967607003680703048770719240872629379640571077329748828739281770075441660330884779539288220944313294762143588847790653176774089774033399559617) + -7323439484151992757431054484912931979861244043627630118213112440051387392428853497035249623931234821362770902740177541812170377563064854590834087655133962963430877452052749127605572395112726398103244974178157574726551814002744001021805127518246639418981066588073652668879613252372759895389345727455380224104332342029151667860553645106555190741775758687650292791318963679857313030729683299101577207875499929500963723267185390425716927303375831321783415003339099100562942730763231688479910689887284950156875532151104047755803876078837921949287811575034368641167438367411569736575067233548122814012421044943430647665260439418887639347030312118291762161708906) + +(my-assert + (* 203826295936164259559522643510940430939 428315860474710981601019542870649234168732095026625500771233691514247613083810271191136212287636290276352210600151884730196161003906066671915478570992925366265552107746965374246537358349673161970290367972281768471743836339191023211359427335141701167253694144280251188008871929010775436125645541749886873478179599464478734149706121117222690271210887178499620737860802605991262799781279373870647695125320153193063528861104479576369448865373971847676465682752435142074973627172566791961541105525781297462635428308325033717669972726101583722868689418677558787287897456521530400671342257419067050354522203242849353639864) + 87302035331271280954456598486072605056704393103691656908943847729634903654600322194677794243221825233700566108459784062758955025931450719283517278054268553004951352280583820782976072352456972931479389375165173986780482062859853305469143408707179895843295115510597584169486406323435925707638987591151227843652210256611991940374072593149367903739596883229844326054223707236369465710416960023659329202073724249764308867733476242261506975691004092043954515337899900837434270833782490145948781128533218641649564543508314976001614187701395586824982250794852925954991265270537649691628899148413763865280007928191637215283244406869662872539567459561720369352296) + +(my-assert + (* -5899540498246269366107488541138263797694914692322476860852796858749106720144552037986906792251681094769894732746138541066810195167688318229720888479512583 5834015210744942902) + -34418009003174534626858248456163154666511779871358190892629413477534042866009573638264296461516598238780495750056279721797403178867717911762916049857737963922333901125535866) + +(my-assert + (* -7558198374656605586076446665394545534375963428962439959101805545423930654069723860456022097647139432324162475685494459942871728608277717748075653794546685 -2079670855873590264) + 15718564882684481784074014915267371190416032453294568239793060140651422710113447422494938907375595456199203928496644205320139985222135619659630853564447794621716315309474840) + +(my-assert + (* -9442744083812363570102321552182535031605446031706376100893354933468482520577272174689455502380973733378565213055641110431767353396963744600184737808983381 -7204974197101757391) + 68034727473703353914019458883709211780958983263702756416891835054494728840771498925306650413027883039860202168095834137357212487561983607389479135319040711944281262212918971) + +(my-assert + (* -10658732210276096534851972646242288663170038580488752611749460640657411087860047053151548660331707024718100598181073744715506934778234716535781332588396176 9193953347013373121) + -97995886679587166046252015742839992974979220158813197140160489510432960510418039749924861744197553021702396544307690217470606424904065359660871469041838900287446937257585296) + +(my-assert + (* 3330096979672637104536573277593029682675932033891010715180474877149733802060455951241981993421466123791200840797318740359792251505430948855600408060492000 -9413190658845804679) + -31346837782105095097578725347257193539696338226258990009265748336528353873277500144838721882313026604404426563737656928378230261942407473822851842589487713775609448642068000) + +(my-assert + (* 2224201331350479188470378485954814766783857696988331736807430786504130570570323948774102396158334805040994159865821844362926631687258969480929122732089195 10226747830478556903) + 22746346139936030910929166328517425029735137934434969334578972386859485783192993228082340012742115893176871887387993591191632260444955081663604449277961804869872353878963085) + +(my-assert + (* -12394770820700925077767705800588617445613665027183406054209162910642613421436080064653443098327137503596792411463268187212855350864330592654862321763110243 336135860956209890623046930607725140868) + -4166326961171213704571179876442248501325782360170764344978629523457550315208845439497110652079907652744850691289494398473488033083739905461347650605270023127087625641779424751335704552988710924) + +(my-assert + (* 11792778994619176404079667787533709801900490264171877873621265044313417667869688303207909681289642260521608966405181881416781694320672906600599581862090088 -197661229068721548419113517262926820105) + -2330975190212228827672814304508257223671550753091700552243633152084831515892056240354560520878171696176381845689952044935988868477421447557890739834031207059212175922089523097911477486879619240) + +(my-assert + (* 11608994516281296345925963401821217560860934641820086911326880657644311461955556832927259499969983808078591149768068360172431078248807463030805586293656663 -40654941048774156019243747229920736005) + -471962987694958552110784676392477007070112288398143925079396435246284471999814508543057304008480666763661066976653446723271982094424149279649226771823800871458389214002872916339341019732251315) + +(my-assert + (* 4821517917539756801293776911844480642406562140007084392649374723119190602353617113036081438891134008988421494142194891002983491670246762173236312873933599 -255528396376819316172341014108564420589) + -1232034741571035406264710387186737842510579499938716343220834781077329515145216794636313459582844773420679078031627466542930137302257934575129329529129776153159694412903937370462708576694469811) + +(my-assert + (* 7638751115643228563298483305056828584775811590562130101723525925933790010789130133831569153863129513189315440899053288261039147463032870669035935364282061 114438828287750304954799140618669114911) + 874169727255956505920153418854946321208907128396839975975317705220623267360648189969313978740314703015845506506608054761304647627635292132043887080298168302864314697920637105700927041824911571) + +(my-assert + (* -3653826017463740005170218884285271512636869606149686475539243914909566619638259666405831445823138528809165270360144267462878986866506114069923299116957450 215752050445782448772085819939961259625) + -788320455239949216234629350585027855111249573063377172522422069903710014529292638311216050777840734448624510386643245486023092483841464815987597578151663227035102742664709136512524899527956250) + +(my-assert + (* -43242564273985683175827997542883970694363047476880657467026050730764924897992516355909421962249292250047896135687573746158665836208681548975073555418266 4424346097667245771102179669235543742385176589624011161914909311078645828684936231569739522607200308028372644149306431599085361996722603718517735348761218) + -191320070498733614136284309000213964486426347688040889144514933290125387693498098446328694172047943298442181705949005984031677324306763731212307716485454004382079159622650481983102917517993601466178931324415483972311904823997211920702201161092866663969163567426868740120661073974542958600768774774949607988) + +(my-assert + (* -5093597555679260616199210906198149266592665304134802327659606846977583233938836318559188141955851256260954289429418183711191354912372372976165948043123133 -2240632735861652612028397136046974907251405868353380459030143407902436514978447480884513019736738955326732458088791830752499716417751919868492224207936623) + 11412881426559848135724717164530530041659963797467536748076144863846600718211858527283843975968920120508569299672573958424908957105703597501013710262110218780710678312197455759181436286391257283676806548463507528765947919856827004176416634630489598937924092540289712219714362500246928243091408698274649199859) + +(my-assert + (* 6049789822056553589237940133475342650218069231558204589924996117723031491205673061674252841792149409384720347601549237626288416453061224734057079515141650 -826416247951451524584060567988229017033981218652490450160817307801130685352465013890931297548015267655971295627931896259998420078888499206031390299169584) + -4999644605638856588581238481465237523157457201817697008198975191261856978252081380810200468420738807464233192102972784271159116426108806200426852134469939032473362689081653859652824862066224063273799612269941254948709760659691148103622071316554194507524610166457990087959160807415102946877307193349131573600) + +(my-assert + (* -1175978338162966145239180473229656000174129248706173549637767835154921467129547950144109700900405904250603515318348888619371004435353505449762899046094747 8633693716102199391202401198009047492431980605560930404972542822133579985462906768067706391388213605203282586546130434156768523403030127356256666478340720) + -10153036788469908062299722391986722149392791936544969945546931764708792252481931153733789787389051773529081688846141949513463792442701686406966696738286561777611293604311491896230769507535896070984747493738525389837795316954065260075941524322954935690803870500012809797698319359975893462672845329776468197840) + +(my-assert + (* -5083395547684319640767882199938390155755986838939007846911062687871291096073452055061784159768637502151635665247461348347470360218957222873087414506633886 10813098236568616588240471432239693891825284805405416395976866126102880121934298269375465735278296789484402954117593716698067735458182402220278016922449294) + -54967255432446073625448401244836956268872685687128644401372608170106281377801209665004925733448944141633739594240156882328181133879414641109484442890809130544146420476457200729843868300396656004198615619691952536924980482714767859804902602805398865249514544806725162402291122143659939645240358379962457176484) + +(my-assert + (* -8944626200084865988157251013718979706166428261352840753194709093968177704853157211364231059892647813839391802007588961807572842923682104089512428902387812 3814836951264415657788614449012480613328314590744410079075164918748648723114236698412482309581077603776489883375576245233128800002373843611668945838558629) + -34122290543331565327874124324135450224668275222811493728051290368641401807963502623692504750924543845019291736982354932620821594287780848608647686402233097059022704206628297180782771812500512744911371653368388270442874670230118309469599458827222162362901084328510647514081302476000779049412605744638457029748) + +(my-assert + (* 5186176030253526423885531264483408352469356233262336223619904269047786350470477526433506158542551137478071074193659876898065998079440819597952826155782068 21428324964794197485898135923805540163916541943812058590308650649384013587098638034673796533027113673143959572855470411726978105342739938341516634354246514986124789451866589211982659199267654387148420461876524076040233779391563396552267276880650559148637067641021059664960876301072636635299261389450890094318429077561092553337025096293793433968243940381587994428364726938534453507046761494257538813861046058298873206568935790790373886840765817404479239485444563488020955730741209738203470138117422899051269778988135668626686262669881048094388220931264751830393793846372816717368806996496715219806062282836392457741918) + 111131065300898907482632501071313138589398597291097276435916516379173430095773463468344138866282820740991088290299992221985607057347883717514843661030457396422379155394966857856069231504805779448809986906434617741485942621643754096548512120178021034054648207248963478122178145159262707381679354401629366698488021743300737044695960363216253889163551918513521913593214414139637549577618641974388739304727218804595402055185824193445089425262833385286117064481648652550355832014346131722965510192584901901111154083186713580209077544982897821477349293279848852596241762198202012197892321827305803333334823616660229870976569043453639028059771892706354703750763908127611939169337399882784092285804830644630059487027413697220038110815990084742241055099963659761569486906596326424) + +(my-assert + (* -12615422028124847936088012564413126213419674293830655240645918456932358053670311316461359727921727680491520480380615359506308571290338231702217134487397730 21538722931308708400287621200994476771789912594554241036641406577761480056366647329031140922034590767810855360008375309986798226712928670905618807986829790199948665185268081173685941421700542631395958882077936923141152528333121096909688700106365468854487023847026564219531968849793109908193037522063952753477768381591929787242143631287330811801315216116212154423972654430356675401769729358415036943501470085182304183033246682446978634892995900678975109490698283226559860736462409705544079080978470202336645384768211440438501339641775269445439018148409151795830925198162301321965042997632479354427154223366199106583051) + -271720079725309675925162538296715595434811519956795637977932956405490708202732964133816538801099235844279338645471102896234318181092598033040518838847055114923365599862266767493227393553801736813141780001130539648588341196802606083178208108557367013886856183999712817955194261262279080641101769944037282423238147653270651419282545398168930625797556638625301898893565965773914460998322350526545278664715332414172614761548301364063397364632709194713561073496860524124460861314674679928692398440036071116570829193414179054372604203478369755566003622621281005164747628075596444178089558747835994702060740334079222508147598079351187013336751322569865313532407367116553748939535664259669808534100091049960040092785009707220249025633808590643620557093069849490009472441113874230) + +(my-assert + (* 10381022953674450046578890619826448644067144294659610359943634722044183130638243233110364436029778310048006743033299956844491228999113516347401915490861208 -20974871685432829994714153210121536409377362402944992609230062091789259307033495284524234519701670462495676590513192861649457148897274608767543942797542628100823017887236899471151903799837558453043431373811892813126194662218472834650841742305925226558315372771353677064933578639099452438843500601586038910108679737480263349221244638463171088589123712367802373159421798288708123925853179931628847579314900787361946716531755600236755527982132768286927549323465697241340003870259800347640599467922823203446834792229595507968354687630029075884034263531531423883902851487995214646322431057626558858528344843531280263328354) + -217740624416854507100100919338835880277259264187442792458843251425095703739537223785767883764746809214920580060316177442387941385712712426957388995082877226019966428812240179251716274377143798847348759498926420314709056615470455134468678662646006408843897699718742372199854223008996321568642038054564397441209859567556502098420151667437837356649730396360374136203172669776530655738388121236079327354422138744456395348910073462618440421257604563050031602590345028438897601523520973759458890228893913090702884911857207117714231568437403212806578764580006787626657709435954760239671948147344463295520930250155876010414461245194991189183956653772752290656063730950237649394743456230607077768595983629559996700837383822873994717987698780007691157576205450973669241823945091632) + +(my-assert + (* -3984492646329789478973994496812455855595578196959138558282015917391108383154917581748539892089090551298072688793487597623310815918942283997753800645644511 22199897116873160263914990610762123553075230334116099569358672964060004245706770678771431369917479502828754815568950371273785689812698287446020480951417047185190067265849637510591502642000414540862689426343523077229502494771352820057572619644085930901096534031496492870227890836816886496090287321502805172125273822231241073590840684742085641304915656543831190976008986490532066597410386596132766422026234488163435487889876791504407434387555507637783709991326338482319227500686541368087892665100076351075069628862376686619537655838590687615291898971286325099164241688147975845320979841704002364545072665891829427213069) + -88455326811459002089798581395024759975871889172872668466370443703433800509268320055453743803627754859670391415348970278548381190662701716228279482045339649051139909543850883613464992501666524385524517648069873862957915620016943364950043289963237718026629805297916194484838158010754666017024585366330526135823515744339445036315966714684052345462172808299142368905939297220895721123725415007532441824406115746741972351142687017849809593982432484296719999502992792447259391592152463664807498752410740679664044620898308783634092355737296495489953554685938970593890496829484673393665321572846542839714620847185428664388282452532264810310019327395691530430185946743995669191791841546685206884247468693248673484055915613115527492005264289557719000245333079386593840592027314259) + +(my-assert + (* -10672574004830373997900438516438419278676753890756925443116289034080220708922677740383425352837266631691319394850521121221541344600832530724104047804922665 -7307684417326792807224298894786988180161884427390942431653062127076829842696634441114228528164049031680536693195116703321494895319862805505304314401000204515985676763063862569446064343853536464020413910728442475032187317639476018710375702206456631041987826826225461927793241495220512935434301833094232834266749666697332380140380619185254354273073522191066457437931022783436360434167505326773192959291779779370530770935758482422581712556111319611455306383173529090289274267200543081481693078804068524057891845603351773722737987393428313340760607600482724483853560340630587029610437280601010173185018227638972500038072) + 77991802747865927212086621295493124451256238920588746597961055391511562690441964216934615500942858653797884925704270904527938466874924049039962754703188019915846345804228044693122758075602494985337649496117180241872910247079655077012999375809878184011356481981590430241786534827516536543734645410817621964035091467871491521760928486006653992134635010794346993161329777270345449763927429735191213854873362673179799811714902439637861750855639857969259787075469241319618538795721956528400353086156169058060112255274542232054021662809196965752800525093125763127895334967094763817500702626282397394521201385439419885607578137159972521677923972708827090645776826953976605193554447841693259586575931864396484621463004541561908426383260772786784541411548146173991869741515701880) + +(my-assert + (* 1420855003086789510813111205540636553863493314684153860389816109865085846062678305775289632805233481596171530412925552158799875183492757047174905459819169 13897739053062356545217161606361735964779941697726983959749295377836209520566715597422965426908191354971972501742952706730523748574796773473606175934144970768662226027157110240776527834790487577863781140089347362129598158760833470434895693782503529955845076709376071972727346128409008293671217324995682020009675316075606538241192607139905488719485728099428376369506685875348346231688684483781160648420909364963718027571565217314827671844485031440079254478598236877074793221578612249882886835580737423192061550370069895525711885220268707201966615936769696379335772521903910689934596134239331592980694745008817040569590) + 19746672065138309742065153069587996891492444461032276894328314121573439684229636534026409362850111716212254549198595854140809664451286626009917828620279583631575940837712663100442879662416765138504151063632823014639305658882804073655537352377258786105147057375069447099908107785635606190515362082317465738205179108333064680370909383338688734129396788764959056886328471374018961975554190739706996184818378586233017775166959010668462907838359485424792026496574369912033757997469014639705459505746723512361959074802456098328538419933637295482429555127226978561859965498424173552676019033370307387047798600024901453757451579262061785051932535359410827170361533603618131510421439128567361259204833501190218719779570258541358012741265599985490513564378203502703406698160470710) + +(my-assert + (* -25117824099635104147178796272946098711514362630774369209876335291088434247131228189812265510495277875692804180473811834186270331245779845635089547499275113671007257221593872123397418355506777725721168216892830217596134983713752526559153149600553468865338887605949011743043425900799896245185282419637806859906582214420191794114207677635194054239563071023206500505880052007267243210206807805387341085613436600843317096291021780624738422589234020279836961194869688005260369009833026575446099544900581955685627511787510900479881434909308757027825050977932238481841909425598834367032841935054158448815026264505726593064239 7846111496222858966) + -197077248428250572361351389692146917243277049539013604789802566767174747369897711991559940484392921619974209620152008632450612546796556905740493507885376190913893140368029841033442857949219716681475253727058707723386016055991276120001690579154370788782636181079931076758384034193266737114305362492836167078199155929937891579224024229182935372106924021709421948701131654358516297806197381566809357458374057189773041520552821330635689748583803171230633654728360451100477472934847975252390985102859262992904778849652221553818627134153578436315973777720706502751232660284910468721430874674021521629540714057383398858244828214000543075116874) + +(my-assert + (* -12000343217458212092754251360179138661969968218789048702097501439124892987400633614429800307263114371624489988815324366411323242909652002510513570900627875514001409309670202055060404640758548257776155562167062337394219073071639153822126554525439988062676648294108951003012550815746564810508912122306190725453386412796036693387315128514162061147675205485143205925649214342646148112549805850530430229663418469577245456944558387628002442451042105749848177325651852669794048215063957689756465788955050513359977166122710392613631703123491357791351447110169966270916789849428298930624807758982400706608788793481972190953569 15463017349709835150) + -185561515374029078700596518575548896805308728003103939537818954646551372890610870275966055765608887701776880889777402229764948269089126750201922167386201171243298907675542965323275634529293654817279957832652909009385491998537031060285890512199675273422070784691446251899120095880199298512230290860589352290462643231396804350623684034400741386070220057232978556614620855818271117742675632435727751812101639747357642295230273344552327870600519422276996860893842363996198017494117619585153346745838853026029459826407782259598477529242420507010652705302341725948095720110508044256096963772599572721279996322424269691990173052929936294150350) + +(my-assert + (* 20244597897909303129995907707212050478823487084391413473821544089492035634291726811145005824559631386634261268723753786161463497881725871168747275110149007801865428978596190887145324535224079986377522166727137028753272158887188902047835658826867304220850429481233026043496635847568448251753504834367809877190895369288045026559783632709799678639927825194847005181499299410953860627694080906167346078299421796974815616608326704894611151743720515377248152215241639534004099341398238713597030368980166731393247619511322804984829747216779359780372801101821087516269912916462719248736442644433057333788741151270815989388229 17931151643499274580) + 363008954869078360197158713265773114114991766614027768774402465306840646219477262855625957403406166192075865834283840624408916170935610374573318606346031792128003204902147985329385955814330782527184421959263266167048755628089412213360508944817963403092490479480264538027768728303095523018598016863928762335410109567604756183580676503045557867957273324581082608248341332512325136675167966306268035077761004923732568405295901819511346235524577361289712297365403327125212199451099538443576479787130510546755789504852631291774614010584650672707483555436445926222945298928326313943231688436271883746272589347954697213098866117569339490918820) + +(my-assert + (* 18134862906191691435095953372467318196853760384894170022863300447691250350836421337333332682828557871096554531436829166444150586004379181099133295174348038948038399079336722004125999533719492457544642570217406286811480006881054375314838605871238868968956868878182133492469763282800195060849734382249696543089869191257451321764806079423169235271658993054867624410589213892458246001270123109841429271429275464249821855221014782727398959126117031823977229309775211695677345378510417534328974531801634095862859684508240122911023047425473036305928743193594967362216559973174709883576295373749738633873828863608550295977368 15082354452174510460) + 273516430292774638949326170314933525797985748367549139070674899956657807928629067317576809269188258819686207094298714770978509118959142516619521080722291318367607601498107007447014759288176261262818034997399866363248136237609824401265450913244758024085739876914482935655100890803279961929047974391299795570244708811454483314898873277493486428279875241232025231140855860469097028388778917980779775554139507550577255217032521719099071084956515691364008526064349956553916033914728254580848198941020806723485184338914882588931083516851849558411503129184026079582257756707601984686901646494090820169212279581209612798749779318126482639269280) + +(my-assert + (* 19213874382308276075905228027166553836726993832150876980655958901416537033385379180983129528081628446454583401834309285184752924794893846406622935494758142810049493348116192315865522516744262115026742103678965417868790607689989205765793528434388393584537260717130892518011447327847533083474230074174308157934463971640826422302901570010591182715932658037868980053012095115562188975692530473556182305847290196895478280679341869546292639446526021874910117953225154204035612531584978136604161393474554294315903436682283787080297348697922389355209790646124024053098888687638640826064745026930980189268652291562437512941810 3155416591710364359) + 60627778016974262766014671335614995348970065077989108071534610098195400001445248886220725085881796599270026085183075312353388418711598523030563716616967792282609748819081238929738105086199457414615236966895805539596649555457494710621217412773036416007129418290246899690911654008867819945724649185574237527152410775686803449108977881160831441280833577932476667657759420192656716352190871667386955409426879693856001112340390304980532208752863058384169885129364117656404549585836664647784765508649117301622797243353610345828189312360124462238989888436478381583689386509617357901461416012201469794664889076397809504626996523928173064949790) + +(my-assert + (* -6561903839860415551587224953276060627466820222543175464705113686962550773423611522044145975606965294164125376820288981286542044306677764776675868357117109664125730405280822770267329297542599719353907954399688197248115043785617436343303277493146049939491224480136371029084354063731401026459653680017632996944506546122253686805764620116169065663214526857151412139439538335533979733329962892417175374550305659302592107472151941922230309227785266745974334776462642676959433923828440435340579340133192678341787895007461237846313005612116885419002449356480017828933592324336731295317076205553526568668826499450826560670163 14908715577157091280) + -97829557993133908713082095435440645457469053259814412551982534425389603663024461131358343104414088618618030154957456050473312402460589893359522167472060177968099538846750606564761307960896264958539903740023783283814849937681270591589750181462708056758506230073751440847913386576449367635057595344744119561166438538811561109125506233466453974371464999669336530949393433719456191822836826214814780222021267726528396849558417851727452246676857867278196266042327956933753121947589485377148388716839519782819642328655117625818256334190717182923260613562191698788004591479576661108985313450029332968584240383859113741485244318702724563478640) + +(my-assert + (* -10378013547095983701124686671659666242518351347561698092030999302329372512356819420877395264401390796163955327080881297568412490286247154759694714275858127906305200295043241717769593877683535229411640745872559018085757273530771413156968541499388413497221629366848027355125816131586610997516488552323667400115617175682996681969687885201321292153656071894385242141321468096793766926179134511319941715949712230831768643024119693594235207988046511542691719002262040067921088838755337917414526554050602539873232518619281766327369577617796816586064895744680567067970817494102948032924671421242699225194947982378019119315136 30004910492448871409155105619400474385) + -311391367570036811050052853596227388481520279736812036769684195465110674594690412517879149770622679377262288447706750813509857551308594851067359841826754786725926298013483569424123912020079066150719085450400229896983461212531213110847425940968466564079253939695853896434719530729030897976597410468081535234663568150722646854183317007227669132983719314653861536414057481478039579810285535699518386214012059191958557306338432321511585867535008319640705419431310336566447165302011113284064246284641707577414470505948868362067233709611758700034131461348997580441628136979257037186480770286846026250437141175360847735150981343952303257191661069675154710791360) + +(my-assert + (* 6311357747888359229575837883366949670125882865462293491587368290797766017168248637163030339387377997726585769250585768079027576213724941259801478313127113803503561717311996500019522893295813684259416551410025111443510215766297835872165689077882298506134885487991732718254835036694083204758447948541157893533099634169589161496492972953698758234452126564385255035294546278732684663873459439615228706684138982066055370429797835904846166362278557095045056472775166294675997320598469599722704075215700819354957397052721573993997624711445698656580401684113096559767093466880001548887739825916626416328760047783071058963451 -212654096583990292869707082365869207538) + -1342136080095566600483524091094048745061145155430997807005186206704767933140306297188996797343723817220160636373424666345108189275851749622201429179882167381735732553825696482751584102093819432866729465599060815670807282181979889263381844726842751894916887860819210652174987999919869623292751389157233409465756974677789790982740267208982768450215563288024088369480574425410032306456026930809228182100949940216614156925537929648841127727165386031716586596638254705402653861723407930666152691102484352058909219619985877341630210918347460471644327858114815713557305185589162775699323253049631349906791700893878999711846225062306568467992135934882289075693638) + +(my-assert + (* 25104391676237653962996674810232896003857294806799086059884413856421530328279649263948893056601611073815235439115612155497964541323584159786678357898152394779494741995735881624055133443980324145256438160990490767324719276757840825641421547232460969806196141938571103617707677351907526127993230143577974386169402623023560579220343920203666762052525898442578990183400559087522259053245822827313206196194989095468393682721753147596892214609346047051670610252732846805143964713621673722554204896154742594858056891979146566683467510164875593192581407047920719605560716270697985110227952698114701527191421628561835164291236 -205991315859231724218751687295926841150) + -5171286675233738337789203670843122752625713948587464573381323151628930998435518250812603433784823922283042037694290795352461861058217142213862777203850665369756106838860420507328654214723398688455622487003912073924323587826356928211672752672052670663842775836967587150049181838707784871641183683742967716787111671792311389517753578360293551031540853470719098360013225516593755039537796518619542838794169319227197212817921098393499332268929332950035803734983497370378852859829228973012039890600437082235032378948656232679080766068869430262740600476498399803176452431728914806536862849281928869092524387549297345184969051926149006293586531930828748109161400) + +(my-assert + (* -25971587288596053786734900662696128734726180676323130693160397208008930123341700520454723462226657743365779183466120836187720332442041321870351823609046027805781414454998487673927365486893294110931852680018706479684281928396163669935417207859889405108139261480861908067489849403284000981453574189898304616775302917687860062501465417706095450121596418236563421425311420755550335597318818628123183624214438801254105808079227429950505879366254661664881055965092586612702279548151277733307180663770432418397550642136953750720624507617115504303570076531620003848642167562950736271141440609700821621532583527124386811144839 -182748557863603655835821910989658558236) + 4746270122419629115710902425435990509747636609113505336611751359043717100752575149404352359855260443259846554733621122684788488984010741203981300775978945529551335641218319619542248418128319220383298229263331638090009313676486209764655429828385994626323209879925281409485074778611946493692237774852428345451174837474328995186242262565013937544898941834362941815633750896882758939509605799422068815435202904271722442099465950700886702949580264958171808372530471918175963644209760378395316412115175988232945569517230829200985652504383431054550902852797293952515652017940918628980037316292352828228005975466732028971159947131994753006597870175664981312344004) + +(my-assert + (* 2117427896392849163304163145095251890404997781812823978967013619233450901604407363671467658244435728579079751353560538034596183240362499870272373308111405924505741579887345118857908796509418246599428633956038017783178050402412769812823236255234302205027282366926174916871858199918908361186936687654278623156607813451034087735179167324944824913226799346886951212979149617678949292799645035425029596869092844906629996914674904522806258932192931217652241231736891642224851547474205131131019084734780208254203537633402057673465583362982905095029133132240839391503135932501785844503813910210348239157828902668852795945482 -296778668392678698960782643314222141731) + -628407431508980610909134894336322264939705333430111861505965183839156278363647883745193463537783397824947515214540990712455315080515980803996660089847066076833542492719707493333185909990202372284811233272987993068106356248349054482194817336258302692039392400931536481136340269417905505366385505196886218794044229758585631131853635721528813397816307666671727692971421531381290925317161326036075629905443938124481334173158440927555118173661486114828362551889594188958723424604273078091320087897088472418346754088900034854230711982602435635574895960156993014703292551046970069204857846207328434544990709459402656908170089318995291341536347275682867153109342) + +(my-assert + (* 24743327715258194976385899813930363006464428087412805068703455203318769863096919192538751530954777047772548306936907016751357570434930538612382851621309732767199276228580401695793317612267605312672263736938703887622824117576912830029817460033437752668221355377879837833796222831371174014543622739933433581963103361464022058091243110136610854806189138108937004805781857031030005354158991203388998364340053773883952742645161560754545458260688560269655272249435540890073696261770299845722705104648358053080678920468895189601731801025555650490534399590288852165862135571140382055044665678298182909026026068995867606241201 309156501491030456401354118244509785044) + 7649560631695275371386748526795333430293346807872366006552933839286343590101586516802834568317627508914888989005968805867728947519409222814667350103434422356009252082456906520988877859152125402282765775845766265340707473525444185795403554160270722809642681642831847296672303556012796775586274347178092325226458743113317655523655255626670958156216225968018208281266858684283741496986683426354716284780229004376492833583965647875097951642088252875535823145900129967026856898970545720526282798418382467634180690243423325770596949644122541224189780082061715230852249880601371985342796525016176048518593825361248232406051886794538203297084423942036889326397844) + +(my-assert + (* 31345149697924857384985323414506591310628538098830133854928154990821019223495435414394178930529373634315044777562902565397455028894455733092896622048288278424884040917250546068175763309233883078972879622697667174865833277342334219810618450605650614585133187005110148963483824629405555603493157452295284935004578187488673124814714326405406894084902824045787647963172437833905574178160343833139650913077173865287057167288286708807322607983179910358234015596109655900840652230258122852488289951986129788952718105898226951651151495867246384586164892018870981480003722043190639707903266193064807571586900961788679579912089 2067227180806746570739122295766566373146995767544546241400900414826379465803168632854028593293108913670556431832056563218709444199286888840721753894461468) + 64797545442006646811970698282511426059102976298051534827345388707272469591333019870381858263624490336448197115781363489554169207652559213486772008013638214870324260793199674746523791257170452738018910619029072942848422098770309928561867618844814267276213608306045020686764830302020953883994906997293368193331696747777630621086600981981357507299729947717565760536305785574555255589190221698706036770081438750974356437738060098906046001271392354762036427049946092656701257615490057677558059955825843182799904828201890893555678855718728417223845757559310912618029462136640226686626513375024547351747669476392735304999046232068947570708757930233036922714350584650744960478326257916948676866148362166017752159953504981324652709881831381637989229842766220141292801807437886652) + +(my-assert + (* 1965759082776833678304908699214846485256126608825750175641683294458978302204367346739996602241053060915897480812220051082619942907491598551933638540412113496542245474287364500698693202553692963910123752514310355402167440783023542848697962967771951714434359320001430281377747193083851165947498546085410216620013287853719686698746328198021011905482303248172483782066908570502837009924228011993318265674390462360820566174204659723461994730913995303015012684826295802887547970851558451858623353950391701673651959262042520584275132971807158231859672678070714276061110616753309305801080136339206017351200193800253572481467 -11092241138073130060021642325471345789108575712118027611362686690749327689527135459714040658411176246054106270789083336195599640521602432629024562630323934) + -21804673765518097879589124792137157558586438669762099454880024920520894260754279593873244443852337739758694535682558790532827482894104906218015712179591886600693703465749571299271429989154199263793230178266758966678432691901731270899259065726530463438316383699558373053423999416350780342222940065486831353604365192968606300436304827279383661172824549131179471364227618431414928702407510473319879188990689163932586727702195573766225861364297410904859137393184592815970592502081722125458353280743087607273547490382023433724488604177909671497082747464946083901888849483505451426245881736990810339421864101129619181017696837017966116165703320918568645290788634265522956017905246042460811062666193790657969385648522736090098231379029903772234867701846824572274796526421531178) + +(my-assert + (* -4067457132547237558852016696244696525033953641638067592741078194074861352472861925779476293767777560910963786727886946479865734639031042985368829200802420611189793957001730656623744670821921724417176679009632346904384261431052972127975733031277489967119978909321422086102208644766894305071609385305464547231057263658903212521469801833214062476735046735467944834107695748433481665714184831786462886261252526036621257865158497049125410241033365487816324425563483999957660557670189397770488996359512245971368638615503320507431381893539767352426795415898379765583574977542068222040889423739693921998717145084904555464058 9635268828818063607505341812331931088336041632536136269505180222913464638532245578488168867093853062326136774925531196873279749483997619950077042084971972) + -39191042921786100943542578352486285322085069425292685238158202937549417928185097567102615300826629615520476316505465412722375794150552330462353356124896483739321653441446703127728441315609093330694305784991844511900128172079464896650958648496336601612657347012294121239821167759496102233234525084695798195547141521849769350204659392602605928907953707277320590923278178152903602506284861018886300148663530071056792375593665422754923886137410482547324901798328311927545105456397213670390651819229021443747424183114992653572959318104053511452473611466305149349027962240989590453237778130260105665310067480846969449221473610614214933278048389171979184119355459010233147440293881252851501522689209874112819966647846701257081192324007280573826673895648273593609466000383382376) + +(my-assert + (* -22047771987573494284336211037167956208924595972749016352929724093971147687332865088249749580556015503923927321586913446367676445848750229391300778587369581738560634537089081840938984779012854694220894920437076215176060179241185151442003472788530160589267677502568156006531439509890061829154786579353177129190813899423306499631144919702707240832059008168851983259611724134448165201725432622521420667808597545410136493805873769372831833878868603946583848422310946469083400330960925084024624317866822897278934924368888332618046649078771617892961267312226309927786691384460940015979582201446635756024251269978545916298961 7481502540911026808093162425787184755732317118387068406204973030847892995155568099553397887864257088525242568880427634318737874025160499293315047534753494) + -164950462146458057264341765173378248123415893870534274075422323606836246718538063890359159423074703472625232511667875897808555123518162244263016096627959208397334135559180524195701526029092734741010866589515172934676451385008535538102832400604699294088534999994990970130226363762230944961249818769566697211068918154629209895730969522747736738946126971914549491889482944152891334838234907190697109929512401661529882587076352559260375439428815896053844621297552401396168240947357044985051323834074355418902009161796886350497072010833513601114819625605048943438304411954380599728561071485061414856047768286383287807924135081902458690495890129203192613070824670256334683011083767124852354110322463725619194174195587835939047474059288568764831570274891727391545546467943319734) + +(my-assert + (* 22607201423790553279447786193696575272983924506336369475058795405894123712509544256099524616893423762658394830755129501447553593365768543361107397299007141714383407862976654294384881771985218996697067215804348472693636567074361380875512341556932579903687576929186215185312685712277482751425466251201421842248749944123326048360909954588266368306843116245625635467041934524547983478110533044085242847795585598341867070787331785945399446665919396062565614516404861115244243161694059679274045050270546536781907061002623188435269769778378780371158624481539046590932125320888745103158180784231722265376331553893647061533815 10075764395489719205294189472045365742345400155046712954334138069917417587273618147303160957788995022989479371576840422540097479703418600112174202202728054) + 227784835187493343385594867881830022845566753253174983274076326016001091958812135049265213053390506720261776960833046225700903422206015373488419693650378821159134369608830936915027161415300759990632038898164509761337714774392506802504397626551196717184785586630245704512525844329038355790338277254618639554796026366029578805283659986085947726260520495140332204643887370987929304924491772630534558682402396784510750317396488402942581973350428066695976988812610467654886227733900635715495731445319565054848075104982244316563526232071957624002266648721592744376122065531440026836549316222728280595228806728872537793522244957258060730038589170810090676474272044568671474692128168357087077816573419470273384256552275636517940058764711467508281344270125535855785388198570146010) + +(my-assert + (* 21997874907846585575969651776904015812729615626636027149446399573806943459105370044846476738175828244018281160136531735881270437472624605280356112191272531838028896521621800558410217146758345955334174583639352151367532676985598470747138461153212653362188252002768647808852054182649808145379073620834551216386805267446360709820441771932135218282126427988826945094538034579367527908530151926679515746133600376612899354099328788736038811470295396365432559354070365548930628714861826464935305416998192532029724853617023971964507955475554955277722555849603716733374588174421463022213135839490633927005539569058361144905451 -1400498192750070094581812894241996480373581610489471746158083224360249880335094841398529960182484181641387946900090289855375996313447832474435929084180606) + -30807984052781257825246153008277875918087659020905755686964119182052911551148620538090633516362197112383237624321406969368641524681503231262834662890145617622830207559490089313283375890353617292096501953380469351747504928597461154633889236826060654886877907382241867167198409355653371944304660938495445848950444683274236538890057643038410268234731745456035923559528706349316582901179686671568504971088561096469997823300883298811440849031903066114422309644669680078733839046643542078157684064686933779591609758494599988463628362190034612412739669041368897594110022347872452261447359402810277413572637740870748949093642723240662839444216981630862346445890780016393330114883270596630385367407921496982236074288475142085411632630374714528706189796772213264952893973677883306) + +(my-assert + (* -270155241925436273159477510619232592261228150696806729750247050 15545126743930076938536195287546926534964892301082800206802745964245668351235397 72127079799316080210744562119267314209211162112457416152560774669179705347659265 58427280233475514109627698916382980237252687770812483048907352594138577656301900 91336330475502063985843547526216808965829995610054777216888670176112782119332811 99495081134815818196404370468895496198561677002653930126818668800341380375657337 6904264296552316628911621065724553059847235903647375662685025031963599691416829398469283631386160328944460790101458427909545198569619131058877708293713734 -16074984786353617526516141164566295497596312655026144270863093715961484079732496604871734572736757225277596743795506589617891195569235287256031608792067121393492186703333733526879481948463529609113624075923052999494363547340563039654910799974388353472433635130983731604982117092991918514078659590068643956240711810902756784590442416249652077644077280371860780741318193975770906075446772544431670392964384669681404295839302410058434872964315897505894833409101781069230919347279857855594782111721176074849502391457684148683668165019969667481755384384017844104770253558111588611189351637275389688093074751942960310850074) + 17849860827147993486644896214424106325295064110723402251474432199595968349198253682890653243676378684005650871261983711134190416277366473221365848417375107498764965893729640224952922241531788638514200018520970345581414705756736222535562338748426356003659523260330725662384208724142177900990027225665451069059291754155591197426279006090296512196415617974140965334686090032257444820748820516976632201388937358434205022475303705442914044454220818215336283948743042841946229853366515552653568436171217572212088935263340599371830215580988184775240338748954666846379831467518505260487989636951404886967842600777836444030434816421999334066711024026401362115623932221335906548647785232855815515579448393689650116225664467056283988125816950714780486880294535933597118808163054631168063568847830481653855357008353733414826165759079092633441356914450038756281940532159493763482047244493174370100586359619040444818634156576789665732998111907245928253704097384811414269835758656988678207624731164159069547745777423464124959379113843649940896359346515513936964849811155238140671698227057228045173997904545787593258286212427476788605370334985423461194148838623911634821153061693257996982252745844329344589168264774527631972524787804330730506700000) + +(my-assert + (* 6411564443509812216548163965666668398784964137255201222920640150 65325385402074288043601436729391841747319174569548241717675134253657593233436152 63305037198546989906433329294566491017476837189978173607681765241525113921707860 72383582945810879300930057856704905379805338886592055772943486702915907397618845 35525980101796892634292856352740658817031405780112750352735419884048051630180860 47579150292602967366908574298176357632207539947399443701205872093150879604391127 7775494633965874654516687741429737470333189902121089184439228657893110997221737422210698789286625633365548095171257583020272703565350668755439139356570 -7847653632223099338936161226557020783515367997970448568586056286591257384101422312757649765574456754668588904917800060981155642916520580540801153603733496143328839018174649200566737789874193483124577734129346933208306772618814806884416239295732454033604210880463262467564639515484363761639994642888910703066277724414372379965872478153546766131136324967950786993982228851928269842355632200589446224738709869729930285189047112131897218464505263042012855229737941639093204086147932759923796947642895167078971517834730472596647456786099215405165290569214043431009370032818978995463168133051136053246705694337584724712230) + -197949741939898550383903354028842356745461597695099989904494711851411610441324234089773644533872304737431480244289438922163630848266242200711131210228027234579469457105291847132071566876246332653149194709623963836885480655282595345693084881617726426841183231475364991154699746506928116505297453355016975688761948609740314324443406930215518937775475617384099331839748494157863510168743547396262979908353122625808170296763676837551973930928848463398657587603606321137626467028732193151671337338929938959296176472483674270114824853018199281637976410726195357458134038379491704909997939715446657856320452698914513791221947734373322868574099599391493563479057703049036936132407025278683219316357543078875410080612067641232277376174351958080693019953378024732243763129075732499165068171168470237875348580987967740148512425201518758344757030205911031119619416763996490581551977913711646761182756531618786226541010835120092904291975494846126923510483263978074437667987560077422810120462938292680423746968095994108344184522240467647491991837793653579480334442342102339933473270535800619630342940590477752278184994533764839125736268376640933720554199782388890444619996919031351334561766248781813883867406045414518951152508504891407920000000) + +(my-assert + (* 1669833986019218156514274418186396165434871163342486930502417566 58528969848472951398118375496887849181512821636583415470809040929690124231959506 50098163184827557635697120379841225459445103589988345336880332217224622666020381 90445522698871905833766573423181067004916996574451008349087758531794463581708977 92366726802191504770638415639612204654473958526592425718659284841373421985393966 69096133232785816552402133765198624674167660496399099321713067612475604030259084 323971624832697152056406152359288553860210436839331005469891386690556929684663075996719803995137130737141925308417709520389528780839777347463558171582753 2635514624483961079560488004237441873979133312246005082134175818331132377114926863102436691793380965631848192666106793612266994709357524826644421074908075389316030912936338175907209987972553710900613011802455058538786723149316934049388525865455871552882282353445228425640452635081303490379594663330152071465360003249884180020993032086861074931796165970076448856988084523672973069824258299029863033098237556417571526135639288006133579174344589248428714474318969988990720790226604664141927030250855550010512291136517209169959021730625428868037074528890516086527430801590050720467893089085308995719513895962750896813152) + 2413207990093478676325592386500172980330574558867366638913149256222218924700401110600319869300256745035993991818342784487193857053589994816247466074246569162659879368383295411190237107255160498774228460295857931362161062884154872938368166514128474751716517750517217000290486110198899480877593169193610813452614906598055909439037075588626529658637140089909227353944313408987644743661503976835580507054926908821206921014266535160031749397432350114673787218438589065861056449106115395189057409933330355574558853874223262465965933679584884152813357065227868165556818717270584803360466149860292769520737249610469675917864449261901859162854558012721179400237645357401213337423255109839806528503425658270050436129019270883446965562683284298538825840361267548675967778385927410390726055957928634152514415917053614892441910675109517307682075989998558764742821214685548219206933043196677521610851950501225469125512893859254575460130829051324112015464552874242522140166275233893076603452098841950130740353331198999756316969161591691095397245996664755249875720008141774247384884623389430842799829690618405724986702942913150258769060684255363816662231923570491001519802836627028431389746450987110456127797025006251203111629141890634728548553728) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7853255233330224291 -3336928547114505419)) + (-3 -2157530408013291966)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 14068934522023857270 16292006600125740074)) + (0 14068934522023857270)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 10985143198741137410 2820546847025452162)) + (3 2523502657664780924)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8108344024060626734 17657489924906565585)) + (-1 9549145900845938851)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9793321542618752251 18086526939764980195)) + (0 9793321542618752251)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -17146297557940039430 12031974228591547856)) + (-2 6917650899243056282)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -11002425733929018635 317353195315898710776749437474283191162)) + (-1 317353195315898710765747011740354172527)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7045772845268193739 -89864936462331315327547597221973588375)) + (0 -7045772845268193739)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3519209948682231610 336646025916394184314065151550367317320)) + (-1 336646025916394184310545941601685085710)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -14043580588957562420 -222396907959379818229719625081455476397)) + (0 -14043580588957562420)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9551193686327136711 75278849342865310446781730521816023755)) + (-1 75278849342865310437230536835488887044)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5159693807678286583 -271047212583781769863421872046042817014)) + (0 -5159693807678286583)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -468628810409465000 4096333242794181573565417750313678008664626221486481835906739336082806890901464399325558358976385254948318232837795406709018062193288308568894691407903633)) + (-1 4096333242794181573565417750313678008664626221486481835906739336082806890901464399325558358976385254948318232837795406709018062193288308100265880998438633)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5244261521146873643 4921965954460062114436531997676458648483262898583452823054595308486273272424691697564822554202559195140246785942292198280651275061385828405859241079703409)) + (-1 4921965954460062114436531997676458648483262898583452823054595308486273272424691697564822554202559195140246785942292198280651275061385823161597719932829766)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7155077620310044967 8812163272024170253854686552273644496512722723120222844613502711675792665532423218585794856067792762737333036865054171911349107383532358686613366666267909)) + (-1 8812163272024170253854686552273644496512722723120222844613502711675792665532423218585794856067792762737333036865054171911349107383532351531535746356222942)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6816314458740361202 12075686527410596248188273566406493470578404199548730085391183041200273406509336777783445118538744079686672261898288597639090345296674064493442338947240247)) + (-1 12075686527410596248188273566406493470578404199548730085391183041200273406509336777783445118538744079686672261898288597639090345296674057677127880206879045)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1890766085089344496 -7408951123352997019624764400646833541081866912262454311449242781355699966135127365870537542305320515188627454777019144990896651509964466134772403923321917)) + (0 -1890766085089344496)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -17760474272160473768 10671898954663586353020741847122236830297651230263271051052178674502913972809415507874936117140992859978582852208528956402833042707438860216609301338079639)) + (-1 10671898954663586353020741847122236830297651230263271051052178674502913972809415507874936117140992859978582852208528956402833042707438842456135029177605871)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 17203040353218460773 -2087162439393804055245476778327445230668947133920484097696589818636894139336038424853265430700117127209095408439503149361955520500062568298413951113007815520417010757436097548975086796164496676384718866185751276003374984886645837833063272909444571294955778352876647505220277070946109654595325494251711661808952794932834009121950804034627054856954463330684354292113876259596011570415522831755074832239680022834732540878425796300024337145992774113324576942861121693541507092307262607720008434123040550199401165667835993232451530119579950363100932584067714571588474895040209606410481479858029354372704983248137195749442)) + (-1 -2087162439393804055245476778327445230668947133920484097696589818636894139336038424853265430700117127209095408439503149361955520500062568298413951113007815520417010757436097548975086796164496676384718866185751276003374984886645837833063272909444571294955778352876647505220277070946109654595325494251711661808952794932834009121950804034627054856954463330684354292113876259596011570415522831755074832239680022834732540878425796300024337145992774113324576942861121693541507092307262607720008434123040550199401165667835993232451530119579950363100932584067714571588474895040209606410481479858029354372687780207783977288669)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -669078238914427842 -2079683283534812796000190145696654156804430677578086735229530182730363039425073862859919937645919418081821481495275802097707156965850792454067873053943961704938117974314269568411834037549827330778321735965757574814268024643310969429104824266062514450939201453648232801402417276979456869834703061150723202264463831469016146310260625377771326468627250569024458585844135123967133684658903385261562998370487428947011971199332502829621504477139578507890165895257527873153869666215808793006714467381179632834850697420959155528830942491523671012905291756947015477293335637719271764878661266856465788562934083754663149622043)) + (0 -669078238914427842)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7327608361251253460 -11696871058150243071087622230096689496181624466205249401376348902965608647385664229774648233384515557654898456058685820740766304363182039373157014626506361274439760335671626498691756724181737933201816787306863365879304649516313681157144055793349950077334014446025781487249267998958541998722387302987853596488202173446477234627919885268339967510098356435511938337505060706688248914394292741973765745281640737883810857064447143652281758869836897346742791897670275478332406904414773228555812810686551346417028168391700814494167715137071887755902595471083839770070956620494992791342919563605887139693691074220696797086954)) + (-1 -11696871058150243071087622230096689496181624466205249401376348902965608647385664229774648233384515557654898456058685820740766304363182039373157014626506361274439760335671626498691756724181737933201816787306863365879304649516313681157144055793349950077334014446025781487249267998958541998722387302987853596488202173446477234627919885268339967510098356435511938337505060706688248914394292741973765745281640737883810857064447143652281758869836897346742791897670275478332406904414773228555812810686551346417028168391700814494167715137071887755902595471083839770070956620494992791342919563605887139693683746612335545833494)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 294675307927425004 -9548883545732446060252072829565833006884749934819836721462955213854827688043000170303649263042149519854567992890424662453846646328000352698376041008580371118805742958892669824820331301849741711055204656684075622499980143446475914450482604391515448002257899292716976191315018524528823574850034894770209999447615978958086058881855069519056370913875205852377738400734853568252684386414540818555760214483168738870291995504569592275824832746669965860852593991220739290892286776371571179317949624919667076576237866033103387061005489130212740740367035039239029315995502459013799346342754507246725497131746887762156527202924)) + (-1 -9548883545732446060252072829565833006884749934819836721462955213854827688043000170303649263042149519854567992890424662453846646328000352698376041008580371118805742958892669824820331301849741711055204656684075622499980143446475914450482604391515448002257899292716976191315018524528823574850034894770209999447615978958086058881855069519056370913875205852377738400734853568252684386414540818555760214483168738870291995504569592275824832746669965860852593991220739290892286776371571179317949624919667076576237866033103387061005489130212740740367035039239029315995502459013799346342754507246725497131746593086848599777920)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 14347605674351973575 16781108313723465798753322947549009969874803839178924211234447140560213638432451682705091051257464849827979202356053729300113370530117630421654608371240669238603643549128642643200948947465613904905607632005913664436128507306181734648889038561843797684348733053132088104433891457988693229945931772136047702319895617567109469705064237812979865949533824478284021673220084274688077361876364538071423609125747407610677136416454538389383594373243559248761308999294417964846813960148782443892858983199711111035244418968070018974928177662516580063782128203214203321005133744081558995859628472663680467632605080081460859254457)) + (0 14347605674351973575)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -13687180458303546035 -19965807258690898827399047857329749541944041888361526571512375013574840494217451526698619297248029675659091093507275385543103914023886879938416253663550378748995953654394575052030527774451712268159052917447058332864628753215292671454945836228787137495936035900814206996568155366945096185932229795907560606361081170245972586794828085080152240904698184990372898689089164281206741448028676272453255619644103230837682506759429084083781590844603079867247577101977877828608823440256009103689824572652465343135798570848914557962085239341382269526989381779235955669274286569338275810475113610787290242075588029043316765795281)) + (0 -13687180458303546035)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -18925243707105550517292233464727657082 9190307209239173280)) + (-2059261271274988371 2728041824926269798)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2268729715267556753620172461333386061 2091801429708129323)) + (-1084581778674907194 1902605633041663601)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 240105871177433673480858499581307555362 -18137436669813972164)) + (-13238136984210147236 -7622864679137983342)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -262280851402380072992262860428676408462 -16900353177245877861)) + (15519252683754978805 -1413263307002672357)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 232088877459084367318095567773397104766 6879279671528853911)) + (33737380734733937751 5401711328350210605)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 28127709642032836544705999676759725409 10932535648386303235)) + (2572844081801336427 10537089091686284064)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -306937202176830380291551701368328539229 -296436198830834971825518518346845101512)) + (1 -10501003345995408466033183021483437717)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 53182351345555180643155906117731554036 -239211638592486301383761475381736024507)) + (-1 -186029287246931120740605569264004470471)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 280879521805922529084106054377533635149 86259942955448859132329436894499980462)) + (3 22099692939575951687117743694033693763)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 270479016313808755540727122565065208981 324912300098276215771804552548480817149)) + (0 270479016313808755540727122565065208981)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -36931767825051824504116995033958612864 319307981922121038618879980001580483695)) + (-1 282376214097069214114762984967621870831)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 107405040163562716679444439233633957914 -141652913538112981614728925754765362880)) + (-1 -34247873374550264935284486521131404966)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 184790583924323275311064238756309559899 9405763068924930772523308542613843828189472529194204592633223103364008985533829727911596099340788835060163612329614413033927995456162272921833539208882402)) + (0 184790583924323275311064238756309559899)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -232146313651929815140292892576650425884 127874042542498530491272428412953321188339770863893691736473766303033699167382382296818126363236257463426694846772750451609560841554300961480864245159756)) + (-1 127874042542498530491272428412953321188339770863893691736473766303033699167382382296818126363236257463426694846772518305295908911739160668588287594733872)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8728026917336931021644334642968359261 -4025737651718879467086249421940400743845718511565541383201031450532496911741243591880148294568060736532264934821412351158153056198557273134546519285439196)) + (-1 -4025737651718879467086249421940400743845718511565541383201031450532496911741243591880148294568060736532264934821412342430126138861626251490211876317079935)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -21247806463473594155821742168531145877 9874623814693251335287095436063900170315895560443374584548447111313954604343515085076726174459237734570523327188441412904116251434030306488421699399082287)) + (-1 9874623814693251335287095436063900170315895560443374584548447111313954604343515085076726174459237734570523327188441391656309787960436150666679530867936410)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 286071012976663674972497644839812778135 8117963470049102990205107814791130105126121536354646949522748212681559213640860255350655907507344188574393108661850973221437234442503731759547377868482253)) + (0 286071012976663674972497644839812778135)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -31984072490103846239901254171623218449 5692584577100138206704178766874348327662006017031045734962382737701553237360572309466111381682998567474445884555969155997528896962520199289069413649945515)) + (-1 5692584577100138206704178766874348327662006017031045734962382737701553237360572309466111381682998567474445884555969124013456406858673959387815242026727066)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -118786321298036108045826901623494422286 -13104687393529855246189161514016061367829206536234756076440701117699438900634808212710497707688898041370523685367660273492555927331371333817584456923437812254937564791326005224466260676246116823279440552837098144298072108885163702544652442198253976130758036230979750526665070549806140578651660117367824058664768255971820333797528263566114021182845197585116811208610765478558726491630221448907739229750716647693886681440731920621825762708622208585945445501310666367635378515829380161368994361558247741326227866296163878689192696502960274515396418704173356117106149549811507516298161494760216869495774889685228097554343)) + (0 -118786321298036108045826901623494422286)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -243504960196882294351576664380857968998 -21587937181410571895883243216668490389074705797891859245233974857468088393972175783210897703383951091997858590608339069503309630378648345491373074180865032523580053667127292664354305946146706860083207200717386662398495588729927890691458790805600368902559075452315483293077820819619965677979632040202844747133012382862591603017396270452230496812292060122531819615885125296991557805051862986461441377986436031061301043809602913037623299360710776463563079053501286633046825608308134411478010516309133407298319800662521169341026639016773610132691088293480775753098006068864600975258749129292334356727402877150032641596013)) + (0 -243504960196882294351576664380857968998)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -232153120215337418381368832017470265942 30369869998519160635038439385899036531726274899243107662193573776561025086030508184579231487739439638990032661366370630132003795988534362627493292132764049369361254377811101088096885616264297545296183017838644655031800075015262568240918564555865889092855166242732548296118581123607728694721796055009838837557999873738362196508994398492388283391000153200151108985088421583241872508945550713986000643154770628316896294096213588875028875159647959209523043158262383137987983806573391208706198841017176042216759223869369001945418516819972673432636326816040752486579776281338052626173120273068890045743383055115108151149136)) + (-1 30369869998519160635038439385899036531726274899243107662193573776561025086030508184579231487739439638990032661366370630132003795988534362627493292132764049369361254377811101088096885616264297545296183017838644655031800075015262568240918564555865889092855166242732548296118581123607728694721796055009838837557999873738362196508994398492388283391000153200151108985088421583241872508945550713986000643154770628316896294096213588875028875159647959209523043158262383137987983806573391208706198841017176042216759223869369001945418516819972673432636326816040752486579776281338052626172888119948674708325001686283090680883194)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -259060284965774946595436776839639567158 -21169437398760148980356190208468018621145492999838564155598571671707045137252408058263155870788514173361612648418947991691931017566701206182096411121805142388703524692384188551391839307655250861401059757668540803453257330609840260191124331324376455691656017965418225557221321063048013134701879342357330536176553693912196231407222911508076200690973402778332647229863066211873019193191946948707769594605725700542299351271155436324879464212647734978854222464094486372144771948169422844206687239103281296767882465060755610256361348437002775612357787333990788742488962974294617778863800504758143312112916148210635178700875)) + (0 -259060284965774946595436776839639567158)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -306407220440527520801126245152934343544 23776904469041910002999929986640006577749806048379780143306978176280330224333859620859305982085584460504452577150094943864349273103240498588108336792264540481132832425653265046674475461727185564436156797869482735166850827691928781085870354146365177855543550807539877079785312955597311473866546268560309551339704009052837019611095284429480282839060448969927393502922337023493529232757886223011597039473438267362519775173848264262428693937605086393282678388857244739695710639089112115821491015511241179389623611704128686301802869094211111183507607222840602723592206395532989319304742353354849715544201896997806941793031)) + (-1 23776904469041910002999929986640006577749806048379780143306978176280330224333859620859305982085584460504452577150094943864349273103240498588108336792264540481132832425653265046674475461727185564436156797869482735166850827691928781085870354146365177855543550807539877079785312955597311473866546268560309551339704009052837019611095284429480282839060448969927393502922337023493529232757886223011597039473438267362519775173848264262428693937605086393282678388857244739695710639089112115821491015511241179389623611704128686301802869094211111183507607222840602723592206395532989319304435946134409188023400770752654007449487)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -195344089877883615473604540022799066156 3662747206396136814780716441352319011395583880744440623779519524132715621398922492090110915810914165138435343905061143614931233310311653264955206314385113727380922840781471233570237875610273247058183529977038444774890036917021403875269188605058323112809901006876685005810599540694986877767813641408707144817551209014119080068666341132956917595575721029282915413432788003670940873484464479035116187361986468817764174983360339341760904395062935668506379254915132158079325547293981795720009601997338615068852024788929328937759791477545407878160402653256560646902444406842976796122784294159073232675729939439754133572694)) + (-1 3662747206396136814780716441352319011395583880744440623779519524132715621398922492090110915810914165138435343905061143614931233310311653264955206314385113727380922840781471233570237875610273247058183529977038444774890036917021403875269188605058323112809901006876685005810599540694986877767813641408707144817551209014119080068666341132956917595575721029282915413432788003670940873484464479035116187361986468817764174983360339341760904395062935668506379254915132158079325547293981795720009601997338615068852024788929328937759791477545407878160402653256560646902444406842976796122588950069195349060256334899731334506538)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9264891165355739565190184416501921531110089392234481682785663537978152834210043205322426048946857682928713233093454298987718151514375312698287977140085629 7037874176512351849)) + (1316433191754927814343121270936699199595699278862016004420926865721433832616431797693201713416985056700387482358940219476958754936526117 3725966351458345296)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4200307032774171266112621290628586259036811354993551074625290503853725932886889027855146647188583607214617803535833936888841730747156500044307235280341823 1284895891758199540)) + (3268986273297707492966046995014614916998242647231210827092764188090140439361457237468815188241626314878458369000334553644889671709204514 686385384999618263)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4633581426210593840116821588308941075113609939505374670564216205139790589811590001728944069668539972864711443927654873778749890460797761818777105143436310 -2962967916964005701)) + (-1563831116658993795279542101101791208522139405163357327177345954575873595639420625598557391282445499923781922172975036467881769387028636 -2305528351410817526)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 12717552468498637611743035736272812618998169576927971614333302239794587794960622996075191568720328790968571121428403438724885597787608886055291630047062012 13314634913503466421)) + (955155928128432692468469826248574845938797371431354312846155816839032798664341688948121282840353830287784283921940330056923616110441287 3054936783550538185)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 12062294501874959722722826646961478850437392058690935960962546316456440331759806886386062852332964852589981740852222339370133938328830299239599161668985128 -16763340409247566945)) + (-719563894032763567901416565485723597235798340734444183600832520303761799320002945942723929422229544393458648487318438477478730610009081 -8784252901936442417)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3044847544275515285523698330617680562098304367055502952571345800359603621492376638228899902071703358030930686556600015395721763778348780143354036450288026 -346996692199522190)) + (-8774860431593785670059820118794469144363980632658525112469174051232043754755411530275560319174086707639904288765947602493995823751245651 -238735003065207664)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2509912747961300370421908848463238376627618739583712646450568707494390365647434163992939257405972498499963653610934135188560348612028561201284997136414467 -103539220471632131715513528655357150478)) + (-24241178719797015812049763065806339919024561304709065585003455368093218973185992185403749066840410575011438662859226 -96472873114015658715754743886276195561)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 903584156603757584665316743639288345339689627067279191353819345586609786559389840933430566508676924801215959188934167984436460131912383813696092800782502 331768089796013775863175470747253254043)) + (2723541486944457282998823558887230609702011905460231484608706829329099534108144630923237396663979818212898288888162 206235332161320659528701690369799443536)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5673315779132616764913839385550510388979090539569302085655840858178135330568442902409259209441411672724870197775936862625748838206738247202566588717953664 174314453261637397091517016624017866910)) + (32546445076572334426551736182476341541840123356058415149120265601377736759669652080905093959104527787429999911903291 116692109360780668718335531020688952854)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1042174796681883628708939541235268651605049912220225874766096393016094308719465113556241387514699104237113811358810257758037463299809921161083533137718034 -222161050831883826404696847740663687900)) + (4691077903977550484144586938760520043889189188344556635834217114054282381408390083982959968194813858480017307031811 -99596643070173880773679158795261931134)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 514620852714641065399283188571474686623886013323210978774935263256584816823822985571618774823719005380283570413767760460152207111047429811764462688164598 -249379962778237023348159084806351533829)) + (-2063601449697349844851896329155481297775287042332288194884672211603708613220802144442049441368964502372230090742486 -95322380544583572818596570976868394296)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4269600385716644031357008587416832262633392539755787971157199376810061034292825362806383550016756143465036715717235613514913396047178769910869994174370663 285417980748490192096950554131180300340)) + (14959114960171371128118740711875740516756226597819143207915053559296218628291049058344647983358827408473567791787490 241314195989544958480263376470519624063)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6257762944066060502889009610562625466881502649685643619949901701091938859953222566838296129679249506961399045004819501125771060525963805468605899184284857 2403901388951678895074087838271029994884292204266026258064846860089259517515609086601789420041871201768080771502802345608184755582676267305500365461987443)) + (2 1449960166162702712740833934020565477112918241153591103820207980913419824922004393634717289595507103425237501999214809909401549360611270857605168260309971)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -11993484600336960787296361130458404039545119394875472848786275539588308627572632551925095053909141197737731742215007587172062102742960429155637516154567478 -10601606227266649325153572936490025724316912773656025997862708934485961793376598665748396482615905529759961488391911046336857148489489874009257983913322770)) + (1 -1391878373070311462142788193968378315228206621219446850923566605102346834196033886176698571293235667977770253823096540835204954253470555146379532241244708)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8099353584218727402496117482244315513694479151831901237119469501251316930293170263154474101121202090352876083340578448720444998702069748972927117400667238 3544314361305784888681580682051379178614889611356920001389193108853540699763802421224233206957629368752496825814976307915371579698349690086107445288844845)) + (-3 2533589499698627263548624563909822022150189682238858767048109825309305168998237000518225519751686015904614394104350475025669740392979321285395218465867297)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2978635751180326260478380464684854159186938695694356726729544155114559498149136630265180287452727795680214540092030170434165319182046797389540988376220992 -11044560433803724847345327269572156674554851849210901400046696801586678634230888624140822828361962132102290537138655249676050009778590939633587416463610415)) + (0 -2978635751180326260478380464684854159186938695694356726729544155114559498149136630265180287452727795680214540092030170434165319182046797389540988376220992)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 13340538348613289212198643243040710073441733600226599862111857175429956610033827913042723029883753278922272401272143183977342753296395660841047710386806625 -12505012580354283714273335370179473407347376833608196161777727706326565713505585671787333065372262611606233460666323939469037058474587043990269917174242835)) + (-2 -11669486812095278216348027497318236741253020066989792461443598237223174816977343430531943100860771944290194520060504694960731363652778427139492123961679045)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3452499360915990528305851079744650498637858290301947784400848134276013289408593218875969649149167701046100505360083493320272180164238716241369492874982856 -2841735595132421145030480470066423226109731223189024018875906078709951146850527470934664784555907173906888591079310297248898808599295604861461544021697908)) + (1 -610763765783569383275370609678227272528127067112923765524942055566062142558065747941304864593260527139211914280773196071373371564943111379907948853284948)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -12837726014506093148099404481188410844577204272048603185395045047349565142592994407238657335674129551317417810603584063833795494760777857363295221929632592 -5400672038070763758928059302309515863608512780764658336296609520612929827128710430832496604060142364086061442480255889774184624927820479974807630834638627053061502551989845184646873008822134065011205730341955561862333543891572685472831543459711809182159609688999832404181689665081467086838440500602969410420032314939424736094367166550148605570451238900811316075091818613634658092771400323953464835124475741159313252328998401218032670762735091435255199537815920258090766640501899817468173756745613666544200642455036991967916355826412137450931256645775349763991939102903236911444655964118925598580974976427195132959063)) + (0 -12837726014506093148099404481188410844577204272048603185395045047349565142592994407238657335674129551317417810603584063833795494760777857363295221929632592)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6578123342051874578301723989032639872736755816906003001838468752363433436477439123182015773040480790196872643618542950300401093404997067180920740266777136 30227534847135453106177887048045830910966009330493682541426640262878585964314188306388368740002450969080153107270718818194095421631888634061517731024627240634873991685067246458822125591350775226166707968203074411304172314390138208453777131423508042090910198631120304798774511984974823253005683386272038346156403540545900138637964682890471751795844957640450350739073841005154467987598913264762974403365908691068629911370262907886883158252280853615622312950774196097179304856495254526220900137020823369927850276669023897589972466867500466273084668060310345544901231841857904496215091732346299276586847479136514947400671)) + (0 6578123342051874578301723989032639872736755816906003001838468752363433436477439123182015773040480790196872643618542950300401093404997067180920740266777136)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 12403944923950846249231475663107427245396603223802100275104415443763524399953865335344297718622152249002880852792246968794311649331174399649925724682365691 -12888526328266820415927145054786787145889555649382608442248161845973745960691528655550360088202102799744537495406020539568745771467756467183613368156733378808019164713600978887019905699871417123365613340681673916006626966649924170996253273073733852663021384681382051909095614154557333966638418401258055946731820806422207820872515345183005729150326803604361512295955159943694411555067679327842378949865992521340416781113735936437694218150384351520004302169462501770232864597266654390198260481651327159066598217103147752784312005857617885666670915444340917773878003125490279146098981790584757296196254721882965728596834)) + (-1 -12888526328266820415927145054786787145889555649382608442248161845973745960691528655550360088202102799744537495406020539568745771467756467183613368156733378808019164713600978887019905699871417123365613340681673916006626966649924170996253273073733852663021384681382051909095614154557333966638418401258055946731820806422207820872515345183005729150326803604361512295955159943694411555067679327842378949865992521340416781113735936437694218150384351520004302169462501757828919673315808140966784818543899913669994993301047477679896562094093485712805580100043199151725754122609426353852012996273107965021855071957241046231143)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 10948926687039959668263034501276830818625159748756208667794639002017960671515169323966433371280908617310031465455790806503858320395456591407286777524363944 15489368888944605373650389556533647343231613227589912336942045556008797399070972592836944702007913599282985878262526911196097512734678645706417084706692047107683744531285802197270639216129852640210205547180574081479052109734758880839510339349237982383997307379952940072013079809351763653427560483156946719035644278683384662348499193303099798764213152890786143522348717903997482162057330324665060570551176318195643585920374603137371921517627526609290876303058743280212715019326447206678291320236859616579863769668727778545628289338458285997742887048186232356815344233169348134282594953756462483528235310248146271138654)) + (0 10948926687039959668263034501276830818625159748756208667794639002017960671515169323966433371280908617310031465455790806503858320395456591407286777524363944)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 11464576772189320419261665628466949872551044398628568459420638211702970737332076526558331636045640676437486199912474581890841933557822038200509907802936313 -22467560825853172479037421968188386486420879368653733048793951227030601094142939166908251610058992921146938740897141065727494001469172869273657374887890530345239013255211792126218659779037493454354985213639803588241949068595974842726845550080803721118359501094994460828504625140423100683538018569820187798018489678377090273255263020908779694768888896507998040871877361662889436371169588814603494476932238384716309803290555316924487478792149178773379217766514013266795383492328680695659480010501872205935050314706513127406414046031915649062646891311739001532048668245929929298605152418405630093221583825629790103566902)) + (-1 -22467560825853172479037421968188386486420879368653733048793951227030601094142939166908251610058992921146938740897141065727494001469172869273657374887890530345239013255211792126218659779037493454354985213639803588241949068595974842726845550080803721118359501094994460828504625140423100683538018569820187798018489678377090273255263020908779694768888896507998040871877361662889436371169588814603494476932238384716309803290555316924487478792149178773379217766514013255330806720139360276397814382034922333384005916077944667985775834328944911730570364753407365486407991808443729386130570527563696535399545625119882300630589)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8938867625495530153186421114297747048040597826172184076413640033054738602015847458230139602813250873350372960139469151926251587994978713194477868118851140 32078375072910127937267277353555359769886046039319229674839329288579279294400524798815635423380870475101996161416889444654312193048344262195882716890119398121411812112449203794619431500846260449790771355510015457009235934372609093350279916863051987911050185220414029935306290325311701907978862607656115228781358052463349741922708496995681137879712967466047121123132315277071458202185149672157950295326835513685167006326116804121841993768353882369640078584371838201520000042076939249781755766637255305083290727182613012935978235950698890245889658464214791358409590524627630419359189066595841389501082705783042993303059)) + (0 8938867625495530153186421114297747048040597826172184076413640033054738602015847458230139602813250873350372960139469151926251587994978713194477868118851140)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8722682937170431050833187146084378340001260037987475887522226657702929497643381574300242436757970258082372353322466430729560481174965555877218498123235127972650642792093407571195465205419575987213014443482975328738475261835806620444520634849116095235065774422144459742716160248838471185163698000228745859478158104063095766855794756463409807333016407203497851105737138480852953389782284594500871170431951978989370255765328498664056929197514187424012915608945460596104718351333193752820591185791608965252963085687083606400804224201063308456591357967802486377986437493144904666736661926951141864058594174814702200209409 17412472792254218853)) + (500944526446044913245854704095754296476914947449773601840238266000641308362538841153234090543298285278030309320940403936325404298435972916448525262079072487832742313980507689645024811947475736929391921911894727993931203210832413457668815952782782949239897550712034201783959782842323270598876666346488371315244615931371511266927466746002593260083813695350859233907674818312186201150675556646229110170730257749054381148001252368819048293261475322932890858943640868603051493461480912552795132518076648186629059596407623028993206501153697237322059149347109211519809718392500920402797396035977014151301 13717640401691531656)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 28355649069936648964480577421600521514076854589748655538478527484386692848040560920378270353295750065522502408426901852657385194373002516782134462463403619404085937808470896616603996134884288656277511001166614643845546560002367982733683422291378278295503032478358197654941019479109634084898326003113897170044006328598213579789377859798284810297339455100733353158770429621612618690067430491463355522146151298846940191011096497912423339688256950368577997428204387561345591508638698782496102293891198658979297125431373501637906166414269821235570899541062164735301390814949753951678580623524363615439367796948526661114273 8633859053023126034)) + (3284238125245742016855698157684933898976923158153988299571059835059738533454483417199061360717949675767825259147742326435714596823475742487511565640155717557287585352355724513814056546156034557507060565711152037955657280498048473524523497495066421726381315710512047045674071154161308957202034177182801687183543929989744017034272683534975659632492076519296858840261469439577557507171156150551483889412665000065287799665100306570592222219949067222441707356112651967102951988787499729560738632591896472356839552808850928783757605816255738706660766653939585897846868373880810762740938652879077841365007 8480542101902822035)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 695804210379264643979583966247939985121477063798866833769029083451619832314943028815111717357207629373097980486420088049066444875218919515464168730784010670913213630418336413807551517181427706050442981412812560910674568907086122536915068847926867597666432252300779682993163510641754139318056267379096886236384894321926559804092457910184502775704660359338939407870665678723351102313495695271753077268239934810069567863069912893064736153816317584230084541663742856849855885433861537874945479324326871485256528265492542514387227516996450338546971631790859699133015684902494112907242906699969802617955900147949678000702 6681774530135049718)) + (104134643759851814351147451693200005177949603843035721223567744815305881538588822665583702468671678158123657386652154620049781061631961328262453617035662063853637317024464861861946266314086911857166878173456014196637218631863393572542109069255296051532325807248516303174349857623773438852122643289226264801658953137748153296436411578898337203701260654377419646372368642303334799023574274991890918545934625239992964365706183254509198057965378271765137299881104144690382322308740670412140492093203922319672781421992523823019735773183797196153517598307995654976625437636949948229208840097078305544042 753510048969320546)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 23793846839231724395641481096168600821165863841834871677817770057997115862268350281729411419898015728222764385314741974298570203231459954889026804768374989204737469979104608191592488617915776065920825549826544170491376474603565313317103382409887303248767928207436610335921923003830631904883475966155908755916279914050461058817604412376332860234542206749755476863494453482771627934874030957391163592500144106720406855489772599751499515034904792907346159848425450017939743424553771285003901024075692162881112993617392057913260097840038314973483416617082316428401467936188718832437149607288888734084245887947167600476942 14251636779665730013)) + (1669551870223134151303903342674455433642542678166026329327716199552424270739267924882373474967130314854205248773422856606186537084529373808518256136223710801915037299873741750309033582768093390015183894640465684163714303454407585554851774795653260663343812169894506517621409762650950455752948417517702896344204545008148927831629685230911115972567815995382195887880974480058637498609515045000261275580213450984765289759768577989085446697886224919418538617830152205807256503108619376475835548388022966261347231830397100233962945745245326537590040744120991719469590787920917431072137837209281279829978 13846244437708747228)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5157109352853249971318864071100809054313778706912280725237530653514718017885603638808994268309662830522966266131723296476071219223553003512249189605920498878997009866938158487186969488205976122254188731320527219934117903279062529020046834522969499499006879142996400588997334123741485390256248878878301063076286830584096271875934275097457786951285271567141607668681320623976130528011279831938224824782139301311433982239041406699687231975177586985955350651094601995816681979048980035660883809964491229857363116776116215144288428315817606755704237448380042774619545204701291306469557276264456990236770565662987790837189 -10013270743141522218)) + (-515027455577944332776599219259294388811187969682242219239790206822600106136108551964834930674442778634657645567794824061780492131991288077428371773780758138983535394992930162959647831148714333399217585802721010849103285390761891312665489859363343081240130486926587552859706337223282598959658826457912110150229463850079329163597771797337822709730777565370953422223408595882843118286956939988955846229075579330815290845722563420243422752650828997772215730429207767090119357203878107337884921705286570049639435686342039828502912430702417787311741719990865608911989344378016685337998208215872207554274 -920760231421022543)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6494479986256116541104296929948745881595810377963953264991072983439840586308068782167240611739100078965050725068818882183756338815160036859027539278041681781661292616356111680897493765185363894557565156777508945778492400417041556530072176186473028646756075186621344659621007329706013704866019055199752880400583535752226648517005237843095412900402261752786336175778761394870284838510406493285835836510084377115102990988520712094164167646661458280428910514014249834132126729469995977022911113044853980749549364759880528586645949565758303087716543654543586861828638440479331739588108393797432477382024670823562517526646 5646044948886972124)) + (1150270684178027997729638025310141697535651329313468129284627631873742535270359534840413194117215304029010709513909008920532146218787185595227269977210380838656683242728568521891853665038056999715825712357842110695616824097006318159870253326008969365677078769387050477555367309756230306675796151995910498740461667569866473279089249936015985131524549691332989894205425117195925594673141706705491188937755834316410829046680432307112608812689099288880996341318638564624566449876699247700823589547245730672763432749619618807750355174780947014272103851229064036660484535227006468477136474311066305263226 3785857158573214622)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -31360864680221422030140415094508859225037184177278863690330048646310966010764143021431123151508104188281687033827937090369965061135751835578522568620174870624326364591751719134017727476315825913896303730502231987133828454596458972192605628269836766485752863341723932456882638706013143064500915331711791221807863285445277518932935928879510111580179238430718068897684115464091110803073393785115849134031970572952341156248906594900067269723116623961645695573540685417690666812895681389324387236630659047254288574908905115640816788218380202062908240234242061857266935270268131606785945960533363545765413571210356588614272 158731480268028865375787109312788454557)) + (-197571802564094255018835618501836237470451780852464910702917947610328490115600879542277218044587953977482033832066853445897949746594340123621010571525423525283265694134335278880857970722363261435835440841138075424370755023622549046990506755720823389094963930373207384718204282462412342807880786115573288541223692700693236309165845190755419998468567231783954117079063183652374494384463667165956585068985935341133217173168221529758860606207789154326413767211275484817995028454435144966634656180655573506329003296926488159246532512031996848763667993503525898127688305577417054301089 22128982064863884081225183621483498301)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6972688127252138459564959519023672734797720350352562732688801457617542500099509865574973489633915033719003377224851429368921013349700580153017928134596084737004044411366993842119504403376959959480789333673755655063117787017101298662107070542628327980482897959181812093955456006698786827411711446400770298021381400926276799694253767942575674933967663793055141073318481678170963516082521833862017762649825976536694779299584090771859213561628651925244725218133964348562464473355036335901024895778660125505334188112559810228121975479770611339038859346371817450184722764849484125019138077786325611240207689562646177214862 212229494710249959442576275005814060115)) + (32854472639496801513625266171869868980490382632885983229822011721729192329270622778562010916862699719016516950898363598128121229189750116863530046554995732003476968354657890095157193194509736774942176733534056571834590366060961121671289385934253368995757730753667329275656966343378668081666905678760988072374390324867142186156887369444294667350127131255070935565628787125782523108523608392770938414227072810340675454608542379054058487857197652824285799185253955626498482144435788461420918351383205430463919873128183751743772403931916447474872579786344165522578418757820262494633 202602247999430336716424978770050352067)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 16146477881044981814872185978005786543642189695578037880128585850657582227346785609949631520306446259385630057714250080634804935779512167368598228578137970013047546260870411704532863029107179381174130047754949458719207263855344249323475379597824225167477700328511898116621808311449385399905867898699564040099050435706021172544369947305690899952295406293447506146823515423102232662385522802025721933657658703659553626211653699561780784625213816227416468145185123310306319508640423290747072654284738002434784128270456278391972933415297337582959158202392632248570451671740383769937167912379559021602080900933189192375421 -20310422672054016316639412907518719590)) + (-794984828319777650694385094127543908631549711061207837016795411776676915426259473368853160688756737034823729254185786121643208845684214393842790938031685686187522759314947140818495607328399712740082388950671812621562726517214947696883370445215206445278987678057453772575168165658852145270562955365137991966349779422574705948837912807073553643238677887356778699590679423929808592396737386221680984966466476609537799000714595283015387280145210362603689829188312020767177147038887361232908826207585485585717770550283815412266616448789002231614634998653868395118016500112836083648523 -11799925147898511149643800539362290149)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -13333386402689284528955650425278647711888918022382802858930735354762601039626630790596510115878972126652469762677159574447095103432811719733783031083771953511074739306201836852090205483055377050725227473420407492132102122918222222661174330427122421429872287465154597256840268514193104109407101719163350519145025605863849817679140939130213133277602018019855074419919415918787364400403970284236218639542926948339939839929520062948689163759711059171596722904754429438151009753108425737178467425999202826949155777669899192519705543679208977557190789421238295365156644743397621766685402593133067165504533347334868817548870 107895899863035416090758241115761545328)) + (-123576395577726995467509810094692559795501216776624732643654929468261569953970620516962817836961555200657486752392956631475337670018968072148956742753944568338154539759184635744464807131713977468703479999463417456632584312098725347773265375061594795112459950102134313707118281441803361728717545150343139196161174674989680811767284271234273952364761695483244122531302983909975719498713709629935106791776293856798291478157380963024628448230576871460269799644149756524167414024818290038046315016119726155391403548599527926110598142014566712845146844517328059271906387663525750970076 88916219636034843584282198824028056058)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 17396957313719309181655810621342598276769983942993211094806395284201495622288603530182348401034532670779772026613959220329662328631746748840677422913897389222211979435071300283979361385673923168895608787064277711550661080470385607194607715097404666355341496134600730286695020337462621706659365279865288817231582460135505994785679557826378614057840182487774381015927951405829305139118747627556929090278010945530871104877221509669969637405745641517281958386251071953311649218819211648218403974139963448683937267881136641329201897530450274203549882462469989176813129608929688681288830465486480047730094845155570312862849 104186547224209978415781641589908237686)) + (166978921724711432713743436094800137505239032223722714964309089009506614535895519867110422644603923287110323367280581626196181748165083370852210731028149827924135420402322644021166934074442323617970930798783252483767604446788478644579242675426052418474560530381252273076756647943610269802844827006798614570113552490465455602498689920520721194207399033534120048155924790694559525815508064767545247429922864279482054330586837508112647624007190343625308333109186981945018060033849826856038685383194624273212670683254990051450794748656874003602039616482791671154071071940218956513118 9689041137085346765396894259391897901)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 26296668029363560180578472840636347646283515109787546573773133131169235303278230292620358193183994696837168281782424510501462932715289179113988102147665778902989371433141498385910026219307721742927641650208826808587628688330897125412814594284814050899367007933796796475217266168539594147019546294897573039387284123267787652073296654465797846788961105602455421819896924940988943972769457383697764285807789932427485615761627567609238909525216550007481876466503244451415718439500787125259366798747857812030734235875561021422659158282642054300429948383202431010170473103089719168265166132037042278884136592980721399898848 -145151976679874338336058059363314537)) + (-181166447959297097309632649706277310462287087273328158550559504514077025970552462585976881228509338936991115036681066334762526041621219901153411893847383132947014037561714726163730996723689359625350327562359371926025189504119439124542211108302015324941630060663441114185165191476531119095379776949183747807676488899740428054170566283213350742091333006110702325305863276507428847828894436119391753135134140918882254262557249907254757481730047992171259860818951015886963391969368286964814563381601392580107247382831740092922947642920341973871311541502943677603328463821550096331015449 -110577937214275422567781046193383265)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -19994387832358687564296482880955715923586831477222916410597818184152857711804843023778287694318724091304456899035183525127967566364649938785565453184727547598671504088541688780249133503129117660562371945085803761853547276588271572826270417538713473845464667687405215144939251922714172491714494707146884856110703801489923219443900691887441959990915961809557008130581221371957930424791112777130507507175854695038524747304496126685506502272017923871345301904089286401283977464945598827719321374155830270851832155999413594990591210770207211404582078047399265487243377424091264415562555479103296829671606309227114918559411 -12290727751262531359522445814787932748157034294075544178515373320704162497192584943859172528304649072004548036058435558708785921268699678655127651925033127)) + (1626786325187686206254527912536268233229423573477257270053889346415589499220953871015742625081244397640382477041911954315181713027690095532216560352291641519082404655148801601548476351855968135320238312168182690718232048560912434032449056943124604465352409935769208624710904989903415445402236977791654195811881494578919123294926181940156782515461241607944723498957864382829554865120206763098110715049165623436566759235599826844834593966722456940122296028858654743 -9304614710679256891239598861411560332304324920434685965899525875715186019084445758952863067134832791421060008856516918122255022315420901512824783987888050)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 29916764548363516315213840380698377536192609328827808911066465815108876776179490417834258307994776308911573596103626976278007330105709262864909645777842169226871227147054313657605129607087589187123503174807369386299991859056839377153696490642393964375926230602462747312790529261100240727992473466712957240583216041201088172946856263144111813006598318253235946940685055230369936673556047728831107329646718919450916347559724523856479721600705891348359262178740659519774585983326669798219391447115538287743254388570949370216658299333436961807924794235560183973249587386381643272943817567729138289488897133971529039695757 8476334091496252719253471844340714224307718865976339399900779938495486609491382968889867250990569753004524377073297071391348967807704774866029247355531618)) + (3529446129120492576886933802306348265603546401021071145489371491655402978871242160302127070993421776756377896228018319062438889879832901903630775379375474362476945682118589732246954574638082665328364641573132346715748566497144048040413137331852635046499249704620713985392482170976329565026453768403409435575238922748145312555307402543771398751056417238642358386670853730480256387244547289563589645563705382910276075835741806800308617595407635175179549186349623407 1121598720662440742988451944089192258208677258393969079460095922943603039995215206852920630773807538691962340221388452566848135314318278502721876458313231)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -30744743258986840974825934925400463284355151584175701001085034454282509186617636999187209301942468580138651572968436145883508307958710953672541548503099036345172087541186583358599035971842953063792288589346835317805238011836025866089112384348158834439025788655670125182111347815257445264926636792871229400549827577321670531162443103810493815924151448637886392962948822485797619344455378736429734156821345757186019132123507024835777255364976075865806996283635073664232613154449751312293463363442122204887362535000774934247468263702545257658938264075634847752288018235968497021028555508346290918717339789336670514080457 9934634309555858804270980126309615970053320780519373855793924975583204316518242194797388422238716941854010764960600214725109000476250489194524103405530739)) + (-3094703066162616114961725586598761886126440000450319657542750158557542422972265973994772432239434133706930345695126019787070526540238058168248601279554005834087067802027491094801318957724338773860374084056857766237802500357570852135835098188033303615905411388899090151866056131910609183545491275118194384669083917607888152562507000146957250511707959497676133004912560741040750644659008842081402439245159076407113469036885418577123982203712293205143214370192534124 4583596897489701137708573201509728063693689464812281935974761545728663079569821440573072545991527054461975034582959468944964678550288258358252037074357179)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 24643502519803888691586762836893695554672668882609252497967357925433058477865049537403781351424439957461939549800248300068008928283760882152105280755728186165336818042947891471506568092832294726444765034759769551554808855491501013689374698042749154404230203678454785382207604303955330803002216399957247238380783055267792042696128953561495320963977422797650867160007702447898131066450706964885725041540562948429789541526915479497874153956586286026740960933319749986950590370162278200833957789772606366304927219928607487195862425188567871883130961914293433624774413725427494180502314592349900074269004608052919421088368 2717450167284225996753981867457220829510500841312068511238048532529427648370573174539553585183069673827813696207263846346713773366926177883038970327669336)) + (9068612486988930041452615817812610262395413380750714216172624755617167719146150429506179809229439286481063525474263171526993584649905549895379552966354856688607031124385144196292585204982548068977456744404073207215088901248836694827956726571697679223311674675917482789361649212542123782029147076771863216074461137218175127751607336902080642274682219411530926094644805942929937073627694007279189212959755881318530033893691479717411893927131774283641886860168845194 2630363844657415178536247490974293939778607568925570410250370678327072798984411202414449734187268017772490491616031334354084510652181851150192386816317184)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1857471144762621226078309760048781819853808902834007243224510947324703640579895884811355396539307768563652552656687272466757001311647739575925654454617797724205998847128737511426204839085303003071906438273332520201294499647651016586411018765198623236956366866836742835368817430092030307634950795461633849978479504285561783793523293571899866834127333885745234267982498066548934305641020559144124243564372784715821253591393010485777361901806233522170298666402318233462164642692695586402286093353406704474285764942607399336515494566976327035651095257443119526233432484730549923908643983835638400244551332963304703341991 362612878824948204766041465498605121983038344328923889813821008133012829955553725429013872301357114460102737976404433762806451909620639548491755012601032)) + (5122463247256360173380682454830667735994909336257131094636868172398931453441644851286253058553683806107714242214425234484025628771776577335533690016729030113210376620329656025707882934177847398968795670307669192526890837607471635669459016090183544133427748745285201703705268883110778706355536331762965138118319801447738265213248123408984033840769670544118622199016226728679039309116650227118501163822195946867970684116882706924781160720494209768961175300546225784 299760236823448232299335077352435634442705524236228994156709162318327253866985319237312495500717724311867426639654094420477947147244359720759776119932903)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -15512250050509017569431653406374218468191654707236673402325185299702995515514048891881128604127259128940966966514594946451486134694476273851559935124397715410737724278746590654901453457150411276548615199767807502093455391898384739629715289928761836102897197661380120487438391395985221415090269132778914962364055598932950972975325423902250870789291669816092405224971234605691036355433974706922342506063057313987759468269851537540937400869685698983579620650290591582484180497444639057157757973753179907365231695893268694300775677678977541920955165836544926807198464657683328635157477957240884116233992874779933793654204 3358541127950670805593397985550958371637657834938091938230318311713415017140090677340291997759883758478618605945079413061265904587739160855880393703427541)) + (-4618746491270258642196486131268015112521835423420717615093174172980857448220383551186758990917205762587881579670823547496170992786073126440511182401809159567300795932372630208424356476743332043619346311088384079059435373790499576304419282368802375623485321283238175405485184862968207039638749406944454331623523507687428477960605913568521627594126207284882249627708423470608914416155986620408793531083231293214124556072929628635430705354422888702360112306375650944 3005102575063606384680566102915562580638230938191281335082512965430334791588194853068845397234960243041587407778382851298719244486316278864423824018594500)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7795907266149417935880848054805638357926463272237741460640947569644048588447722511612181517607450880049915905557897989678236704307693907736247058983016545076253121570693500226105057772914231058133990872553093077477246778482972908671114493634160355090012802248700706280069417479488180111886570768297449284497993155476453139747448123977064178202693174347058572053686548952330935409613585349836865130827901523001778569465270141666026392762544863707172069660941583975586471593214627992137708766736399392527511202198595607734119123667475481080585901379489987633325665012548140296404667154265922084962379380813206642961141 3266322496024458154155982586177367205241879884975448114046439840444265881425140636480586339953113858345978121218157346057285955670573379845528853928778649121198573716895875372950665878135491926664618467827249347334921049358968885123014320008238518111491029267663871866232098994215220584035091470875989416180732388925174422587186795087858194659347743269411322176680238569785902471836835335166112452646235228206195081915725782645939016905926964169376697807870023636080042287120562847150399762713196525578131013908505157176421364232903071413436786302567498639276925676203136397430977438669196132229839190136276524068288)) + (-3 2003060221923956526587099703726463257799176382688602881498371951688749055827699397829577502251890694988018458096574048493621162704026231800339502803319402287342599579994125892746939861492244721859864530928654964527516369593933746697928466390555199244460285554290909318626879503157481640218703644330518964044204011299070128014112261286510405775350055461175394476354166757026772005896920655661472227110804161616806676281907206271790657955236028800958023762668486932653655268147060549313490521403190184206881839526919863795144969031233733159724457528212508284505112016061268895888265161741666311727138189595622929243723)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 11613527140000568192482756738253388762224453894786686024705324634643336086154640452808765642911437980109688560443031730927780624431102238262306897218656077453053740901919490705730434109001630505554615644472687423755323577388664893480041595787444776915986509240983988768996984961291424649229547505632144971266842770877960364848817464904515794389771780820407027606373375049573795106795237627834701205331678265805568350911815774813018183599320960878173351437520785364220474506113269284418886794765499703487689302735252054649064328797761871733823998210784410557300554983737071496100764692702245794941065431902323619975581 7587249511488455291481574592043097850017617150850944854151430663857438629054661904725186504711545142985024178310267212940242316767124495452290378757849233879415880641974894427201010329762690544890887138507664079244754338469394276854749839357593153274763991475638253761900794536890806900100092838214316658164432730592513062527370014192403678448098350118128696785002089891158354556141292773760767431084006166964515144211080310413063362654706066932594296395740249062444674285627590937186704887659632200604451417990996813320236575100574875972599186794102474813935877205799664448604353627460661673753990274449050152179527)) + (1 4026277628512112901001182146210290912206836743935741170553893970785897457099978548083579138199892837124664382132764517987538307663977742810016518460806843573637860259944596278529423779238939960663728505965023344510569238919270616625291756429851623641222517765345735007096190424400617749129454667417828313102410040285447302321447450712112115941673430702278330821371285158415440550653944854073933774247672098841053206700735464399954820944614893945579055041780536301775800220485678347232181907105867502883237884744255241328827753697186995761224811416681935743364677777937407047496411065241584121187075157453273467796054)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7305781671042805086205879027901218372025263744748476920370936801215407682690507181906856060500614379569331564964369672229742583709815447579920249246854986585035499467980872113078927984775191185433409825799075510115669850322522523768142598684481781858254267858499128954637862215107851239397355311785880257523971110240017078879170794103136756816178851155500522519324993786026829680880063502983144325993463559477297984845168078230705008144229777150602704982383890956566628052218375163513110904344758464487972471262152773773566261138354198738738504010228322403241824600361830597196538559114936352203702189317843297305612 -11937423884971453925821024083751259499642447259766781297912835275709052311299551864192658177304486399283699058384364751376568714457361090099824205847610164922413207048832164141112741434740690851620879666916091683114805059397520385319965609291355819302668926633114618391597972110270104195729524521712155052417250364832858246777602394209216012243471719585422463867924602236259070514326289155605995143153426519592268534452020820494702940294360007255909971183689215427975382460838239606147437401771039532404179010791325434773433170447691511043481857627662741058910094855501029573945308325534013127380693322055343068093073)) + (0 -7305781671042805086205879027901218372025263744748476920370936801215407682690507181906856060500614379569331564964369672229742583709815447579920249246854986585035499467980872113078927984775191185433409825799075510115669850322522523768142598684481781858254267858499128954637862215107851239397355311785880257523971110240017078879170794103136756816178851155500522519324993786026829680880063502983144325993463559477297984845168078230705008144229777150602704982383890956566628052218375163513110904344758464487972471262152773773566261138354198738738504010228322403241824600361830597196538559114936352203702189317843297305612)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 17209502052655993695999949678678881817732805080961191774214537634467104669997820051278559964292611469011761231649311262525642916746094372962648405298787080759403024379693612743720557853611946286870304197122036126838107226222151419136402861650399432372524638862075613534601535719033760228742681750726602275976151585576407980278472053570791272866409613117043122126348697545507835143620584132787128003876247255766444872271317786602207376422907474443135464267851639815814827163426470735478362760843575789201717413221027220343295978806345517086041608240978720520050196395624694268550345436208830801369557317350938753101681 -25492366031674865714603800130440722297248675391454036922399382654290017832413394991423912006244487394226853780856833445493556957899686872020567315114599762113500546176766623020864155665149937580279148318691466089932874147998457966225079089491216886106456935347049916843309661581230809710698689198580162954443484103521650233141750002940462046212610545804018834324858009370780731978549694951052575612824613445810777717659953126577086301947235560041125102454055651800601741899891885690488712713049609045874194541526013910595588271596050758340197535035493872183554373796733932414738278642683363241812520579194986842248406)) + (-1 -8282863979018872018603850451761840479515870310492845148184845019822913162415574940145352041951875925215092549207522182967914041153592499057918909815812681354097521797073010277143597811537991293408844121569429963094766921776306547088676227840817453733932296484974303308708125862197049481956007447853560678467332517945242252863277949369670773346200932686975712198509311825272896834929110818265447608948366190044332845388635339974878925524328085597989638186204011984786914736465414955010349952206033256672477128304986690252292292789705241254155926794515151663504177401109238146187933206474532440442963261844048089146725)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8264418404762904935971540586212553189369665581268178138984287355704267971035469114147004054957406066365602520300857203610010249719556414712966642864630190534880504909484466848336120976452116710282569157883499369927614177722612839620755683557142607127318366680113418741529273669250116389195268121444810596743918472573214391707744942602210637166261703132552343842498400457951297867678005414165609775233338084350550320105330065321705398390488050253072298385134487973139665686164664754618413684815943926055617247418686500187322182211450203615430634564054858334306443836925011966962933359925972720453678168762605413687214 5659270408666391096654451960229302202479994399681938594290004159630195588392730314741316662127233421095165804881532974934939182755121225362126950700260935754690609887023434283325604581248499606543036334396521593447377999307285561199879892626309791285854660250329582118972672086769638010239857182094917068742207521552140484875546416914612991626798295801703343486711676899362639653362756374154843829963089403048720579483739833657436575344900585844370562669493206999896738589003961397524062927929845521761767153927579517203070144813897742036471334901681673999002492983666998353060616069539877603853178826800408499832716)) + (-2 3054122412569877257337363334246051215590323218095699049595720963556123205749991515335629269297060775824729089462208746259868115790686036011287258535891680974500714864562401718315088186044882502803503510909543816967141820891958282779004101695476975444390953820545745496416070504289159631284446242745023540740496570531066578043347891227015346087334888470854343130924953340773981439047507334144077884692840721746890838862149601993167752299313121435668826953851926026653811491843258040429712171043747117467917060436472534218818107416345280457512035239308489663698542130408984739158298779153782487252679484838211585978218)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4195250682093770808206657488351701663023767531608220002369022288787894743733460069813218793361969185403525213558437941222523116136985128137372308027033996674188008302853626391013869026313385724383785051935256506784450227965020957296318645208598488161413279403683346821629439117327209071527878791167163980953326296620631874274522101994118890706372879111377721965738161511000396672294975037034526549811513789043244305969633354034500541113123255063232374386942908997046756046017320772897856114275234707703184161983806610888947627465435762937561231247173215724615365040435541390265704981699351563837340527277633975576176 -11523670060248463390302653643248573080204626895667435502164973305972185748470395654926094006744012148505197326052121545710242241891352369937317053719774706293090545099894988182012473466703170157783937873302934404896538337261995680454862441735502556865637909145839304694688324140057229642104588273654096346180116632418345589170248829444934471179206795690822184585196864577932274205101316913141872261673241280391442045565990088555353753789476615480189520529331131737084431448177942371080785938641454814169544682945510387155405628842164935394830439534834414364899293061798829902686953424000191565445443376301466821322836)) + (-1 -7328419378154692582095996154896871417180859364059215499795951017184291004736935585112875213382042963101672112493683604487719125754367241799944745692740709618902536797041361790998604440389784433400152821367677898112088109296974723158543796526904068704224629742155957873058885022730020570576709482486932365226790335797713714895726727450815580472833916579444462619458703066931877532806341876107345711861727491348197739596356734520853212676353360416957146142388222740037675402160621598182929824366220106466360520961703776266458001376729172457269208287661198640283928021363288512421248442300840001608102849023832845746660)) + +;; ---- Test von / --- + +(my-assert + (/ 10105597264942543888 14352488138967388642) + 5052798632471271944/7176244069483694321) + +(my-assert + (/ -17631701977702695093 3931860028646338313) + -17631701977702695093/3931860028646338313) + +(my-assert + (/ -1606495881715082381 16324360910828438638) + -1606495881715082381/16324360910828438638) + +(my-assert + (/ -7960193178071300653 -10280747961248435844) + 7960193178071300653/10280747961248435844) + +(my-assert + (/ -11544909483975853384 -16041992360613233027) + 11544909483975853384/16041992360613233027) + +(my-assert + (/ -5758820541298901548 -2596462557714095861) + 5758820541298901548/2596462557714095861) + +(my-assert + (/ -13056342734667572546 46502284983183419157350605242474199851) + -13056342734667572546/46502284983183419157350605242474199851) + +(my-assert + (/ 12668118634717482325 -338544675918656078399121171905238525746) + -12668118634717482325/338544675918656078399121171905238525746) + +(my-assert + (/ -16738429327795346815 164053836541028518093058940786011794219) + -16738429327795346815/164053836541028518093058940786011794219) + +(my-assert + (/ -9884600460121235549 -53914696297933680001835530599748561584) + 9884600460121235549/53914696297933680001835530599748561584) + +(my-assert + (/ 6753521264659576004 71759828079371803409570464915096122874) + 3376760632329788002/35879914039685901704785232457548061437) + +(my-assert + (/ -6072478784520825268 83641961138289700975241455431547940418) + -3036239392260412634/41820980569144850487620727715773970209) + +(my-assert + (/ -6708950756971973620 -9847903810677323447803434015107261150885944735136350527205856921771320298384705376646797569973415403097847060539915279223391112430240736564839483430569706) + 3354475378485986810/4923951905338661723901717007553630575442972367568175263602928460885660149192352688323398784986707701548923530269957639611695556215120368282419741715284853) + +(my-assert + (/ 11263779860755455072 2292311486393743282743453705144070351222990311578446825826935237655927864700827857707370158936582804478427014131790879562565658386819339761919809732496450) + 1877296643459242512/382051914398957213790575617524011725203831718596407804304489206275987977450137976284561693156097134079737835688631813260427609731136556626986634955416075) + +(my-assert + (/ 9956488981426387585 -12351244248621474338537656633137999145154500022264356186225225426288301330225259889671144104952158102155582320296061124840400655528634050137479515338944145) + -1991297796285277517/2470248849724294867707531326627599829030900004452871237245045085257660266045051977934228820990431620431116464059212224968080131105726810027495903067788829) + +(my-assert + (/ -14875992781716065391 4906952781757522095285156014969507916562921709689447567404076064849249737893410245743456952512717420040816186768213920574809530298070437840356629617118643) + -2125141825959437913/700993254536788870755022287852786845223274529955635366772010866407035676841915749391922421787531060005830883824030560082115647185438633977193804231016949) + +(my-assert + (/ 16043178952268979636 -4962728781666935768923030490263743715131420507991284894489828489607808897271220927863958149140648859077934323268424257800724618076505149638049461104621679) + -5347726317422993212/1654242927222311922974343496754581238377140169330428298163276163202602965757073642621319383046882953025978107756141419266908206025501716546016487034873893) + +(my-assert + (/ -14889985628902581941 3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361) + -14889985628902581941/3075736124701105220602924325296812116294816310089906623707854625135862902005059305428034753787024827094954645083406870532379125275086885405969947540175361) + +(my-assert + (/ -1719613957783789857 19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758) + -1719613957783789857/19860562547348050982501313785551054055826630539673708970554435103060535649825139319625648954889488501680865494719253019921780044205805557658109807483499994523398090829033362953135186523580359552555144614353929273831853529446536288544481045105104526669277307473478898498061888931858821517694257595658138564305517447595298378933983614114298000880741350618424855028965861930329619462261269994651112266861896630584883581092431090390354633458596611690990999635499563944625720180529318327647519405136188243979680965052005899543797270970540925042201315580510136864931200059448645464256385079735225156720340173280541113382758) + +(my-assert + (/ -10969623867482498359 1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595) + -10969623867482498359/1292477254230352575769754773488799598312602810841892384475535212194939033905139960602724737178675944133847094464739764817257836826367652752931492512753561670732296265459534230949226553571982695924178928914002527460943582374603078611662312521259541641138419845784008028215876048965254023368247445173694441960256131358058174374542730502334351759171930973722361567186133851896057677818979314942434199157003833234473048838906103902832115569853657335216793235394595479328932380393044485884605451918890395812628720641212850763944658735838941829604119213195707479940053016354291972875689927240247563236506479099606571912595) + +(my-assert + (/ -3716891004757979686 -19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987) + 3716891004757979686/19452372993227550502015765258932159656814363741878583541173956168837566077148160901999018823586675966076058615847408138956450751813058209394199427182041779436168298455103717521843644244801542056954603631432685194627158423459586845252167819811850263444712218938833443253125954475476481099092216538126519474183531297423759923656571895377587989169731023397615799830371852298135015608612181670362528239430952907458704415974164085176066242388561893721949244663406941558257051263727439679525692652639731850971185056484335828001005009903973037524233097329857690857731943951449292814500362180170793919266389501882641682782987) + +(my-assert + (/ -4863232114852441787 -22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720) + 4863232114852441787/22963038454503597269981750990033903654256693514059439027985256604978917966584414065892146187253799108250061573972673983350956191446047978392921074610323648301008272837432907303975548030552369880338022067315042332692023645592417869181836251486577977896077712912433381480614752789750181208326525834629219729662085632321271870762094800588296544243340047360684854239747242066367921596241226349790282723168222543448385227922748241223520686047460119733024390425165073367321644498280127168757335614077882325524816799960018589278475564547840614315473357481582710826551932681173443524724802157570101916268510464302946527662720) + +(my-assert + (/ -16248276650501285553 -3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159) + 16248276650501285553/3381199474840825715485713565301777938368574604710714363907009216856320913536015299178065264912798511857598595067318796576494480424838898250138649774858742984769125731728430552285782315111538920026330816414650913188340281906359149109963139438960274321560117812365241840204034925444652058916966934904097509799291744775242863360284348334605170437300543978049053839829106628489146216325576991696936733592366926096500684308845306493636196092408597450926695579897293944488261001228478152650490677071497874746121221519036861983646423005753475340900508665494162949119110128646472783016552527735050067363030838015919512260159) + +(my-assert + (/ 18296946401228630959 3302341071702763311560113831030141639804425031433511503765833897787925467295486187687396312611805794369889470239777040624530990622212474466940548049117664906468330871893337410618797113677420975837622378808494314918471282099855916016026079371666730617071364751834080179173620476977670099126230223862266413091012344741482772771219725893630556702028108027870656512750807359335108428687238687397060104669074315031780019301768744978815422943986587389425726602444937024004102212071953113581935989741954695450085391443134273670514145585869912689150728183940456773133212037846765421397201956541430155664614978559762638030787) + 494512064898071107/89252461397371981393516590027841665940660135984689500101779294534808796413391518586145846286805562009997012709183163260122459206005742553160555352678855808282927861402522632719426949018308675022638442670499846349147872489185295027460164307342344070731658506806326491329016769648045137814222438482763957110567901209229264128951884483611636667622381298050558284128400198900948876451006451010731354180245251757615676197345101215643660079567205064579073691957971270919029789515458192258971242965998775552705010579544169558662544475293781424031100761728120453327924649671534200578302755582200815017962566988101692919751) + +(my-assert + (/ -60488682170925814337492051725122486652 14880088785789146426) + -30244341085462907168746025862561243326/7440044392894573213) + +(my-assert + (/ 126617729996196635247771282957911941277 -7166506344996883172) + -126617729996196635247771282957911941277/7166506344996883172) + +(my-assert + (/ -278675896803726074870988122161067771390 7744689831802931490) + -27867589680372607487098812216106777139/774468983180293149) + +(my-assert + (/ -283351838662873779255871649630248958879 6912311315831153835) + -14913254666467041013466928927907839941/363805858727955465) + +(my-assert + (/ -9715584046609700027352634666499181378 3368831995960494221) + -9715584046609700027352634666499181378/3368831995960494221) + +(my-assert + (/ -137493547985106345282009151869389470397 -1916381539906956855) + 137493547985106345282009151869389470397/1916381539906956855) + +(my-assert + (/ -328662747577960331872949773416436800743 -231069430804205460334599495337085157308) + 328662747577960331872949773416436800743/231069430804205460334599495337085157308) + +(my-assert + (/ 213595640581249636406536485951630735277 -48492294677143227478357598229530842959) + -213595640581249636406536485951630735277/48492294677143227478357598229530842959) + +(my-assert + (/ 85922846498729014445816145204889624189 193533957681757355413031965695625196813) + 85922846498729014445816145204889624189/193533957681757355413031965695625196813) + +(my-assert + (/ 24053342958857142686054803491202486471 196417511107100936775397820630955772553) + 24053342958857142686054803491202486471/196417511107100936775397820630955772553) + +(my-assert + (/ 102038936612518756467074084117019701214 -111946989731587760700903475996379168167) + -102038936612518756467074084117019701214/111946989731587760700903475996379168167) + +(my-assert + (/ -3006867214208872584699983438179656913 -234257597822744479264249663225224173340) + 3006867214208872584699983438179656913/234257597822744479264249663225224173340) + +(my-assert + (/ -279839802710533516603863620922251878907 -3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219) + 279839802710533516603863620922251878907/3244112647743502769852782626803305310331045534071805654982307107362388474314396636799597033636575215617240554815450017779373048313695795886893032630263219) + +(my-assert + (/ 123635964546481689465778244982425098404 7701433613491146708866098469269971554817017737111287276993583150548359764165526640986060909954451793171933304569726872785964805121981749276421956645830854) + 61817982273240844732889122491212549202/3850716806745573354433049234634985777408508868555643638496791575274179882082763320493030454977225896585966652284863436392982402560990874638210978322915427) + +(my-assert + (/ 166158110049010486343321316578688184578 4093720847216792748840371965199135052196058344862447621818024731938681519017878880275303125899149558774718190527651555811733139227128378041055212888819294) + 83079055024505243171660658289344092289/2046860423608396374420185982599567526098029172431223810909012365969340759508939440137651562949574779387359095263825777905866569613564189020527606444409647) + +(my-assert + (/ 147416259636838312272435267341375281181 -11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801) + -147416259636838312272435267341375281181/11266711292262839805944890501811605204323255169233519804446548849178247889563130015168799346120099052214488209897402054530713234143622703174309015777885801) + +(my-assert + (/ 102557200511608632541115941654031896919 3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511) + 102557200511608632541115941654031896919/3866177549962722728707550488877109233779215384377007088712280650225992470307822792085413087509167847767889824884877044539352696974351192629898363157976511) + +(my-assert + (/ 47794953079190110032282671989549362415 3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667) + 47794953079190110032282671989549362415/3802290983508829335098916118339496411537222492645529399519373082799614656011270200284796148989094312601047370399228868583158444769807910513767845541589667) + +(my-assert + (/ -169956065319483471022234920202991103615 -9934427489865644196610501807375648335352544234206717324511161205173460054921759084767897792996557220898467288533128078406604709773449948420404563411793533441010236017064154469575084055359823982786110746700747423674942932421964955746280671982635899487781780756099620799397239156211815110739544719746684712086075069101799537802834839550142629064374734870047412916259754010150500874430055034366305216104752636211802195447299210332237598443674867760860326529472901775427058078447963316168327741049511844237329137194533000697525539835371015163158135757326482343130221118201740819963770851200676279882978581431999960842565) + 33991213063896694204446984040598220723/1986885497973128839322100361475129667070508846841343464902232241034692010984351816953579558599311444179693457706625615681320941954689989684080912682358706688202047203412830893915016811071964796557222149340149484734988586484392991149256134396527179897556356151219924159879447831242363022147908943949336942417215013820359907560566967910028525812874946974009482583251950802030100174886011006873261043220950527242360439089459842066447519688734973552172065305894580355085411615689592663233665548209902368847465827438906600139505107967074203032631627151465296468626044223640348163992754170240135255976595716286399992168513) + +(my-assert + (/ -83006311763073652927964071041666508273 13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690) + -83006311763073652927964071041666508273/13480787677843057038436344704360462056114592749322481662307876594244244638227291805757775026215166740035048814729231681821563443093991755779505400592913963236010573873554317250153995160235771659208137440518282824497744092608999871327127239673370293239927529076145825972430101380272357235582367639159280348164804218713823424182167974242317526959809443701996053548231667727254858428867000011055354779789221097183515832386890638024105232865079002765479933320220378271026425568216748186200736499581088153390350474814123049637951929317200314355414551809067125550551841102097159644340520444983020267926123546444838010089690) + +(my-assert + (/ -312626207169475064151212222217866488926 6989069923898656093413456232544365450599471748502878018530391549015151484336014906416216966193568842618920902504390187814247729346977677905224098932673981665869061845335443588666641982676550205160521286690015544764015602751932938178737949961754714143180917985455875095030469699198116593730005119922928175789172042067281849364217595912265452199938281052984802042194034638773435768458457616208103331213440768472281882976004050012769415198321241810008696147179275528426468408383757692656341606162350211696837361434874035354680073309142183699892959618671515841112321607728427286289324836870027735590091451421689980776552) + -52104367861579177358535370369644414821/1164844987316442682235576038757394241766578624750479669755065258169191914056002484402702827698928140436486817084065031302374621557829612984204016488778996944311510307555907264777773663779425034193420214448335924127335933791988823029789658326959119023863486330909312515838411616533019432288334186653821362631528673677880308227369599318710908699989713508830800340365672439795572628076409602701350555202240128078713647162667341668794902533053540301668116024529879254737744734730626282109390267693725035282806226905812339225780012218190363949982159936445252640185386934621404547714887472811671289265015241903614996796092) + +(my-assert + (/ -151709660794612786408772973806200383563 -26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443) + 151709660794612786408772973806200383563/26960472721919005254400858042130056790831511338891584787669209989714807518625849812230185079206081782191501696661436514815190623849929065098497737155759771863508038766934134444191240792356114381746781342181881402424707118515655119761011977116554236461222788625158348668147995099157685699761135150772589445239536582228655532345059046596356954495360132444243748421428095867292294626357084961338288369883088525401649234025290736504802104065029036642533076183281468647642956623788270236516849523210698622687255735945678505925047193818483603361307498423724202227256505312543145618362906047473400380196192622607541097732443) + +(my-assert + (/ 138834496986391136939574372853300933725 -8052690543272184576133758511645801940246473546142520821850130421981395129853341888352999304040698251945886555605291324954368612109314080471658982022831338507499254609048475429862437003158379101603576571787302167207044118847876475134352180874260998595377014195145760071923429129767580115085764485254455919915567128572731355497418831212259648020550107573824886521471697331410754043280744066090848295906051303624846301488010249980896364883452154860562864255354208802313850527991005497484253401461375477060954782095047043919500670383372218536999834862885439984085848342867301834247551832677237328664699302165347765799113) + -15426055220710126326619374761477881525/894743393696909397348195390182866882249608171793613424650014491331266125539260209816999922671188694660654061733921258328263179123257120052406553558092370945277694956560941714429159667017597677955952952420811351911893790983097386126039131208251222066153001577238417785769269903307508901676196053917161768879507458730303483944157647912473294224505567508202765169052410814601194893697860451787872032878450144847205144609778916664544040542605794984506984917261578755812650058665667277498250377940152830784550531343894115991055630042596913170777759429209493331565094260318589092694172425853026369851633255796149751755457) + +(my-assert + (/ 276499207940187081393841843387608369874 27347897028734618663428054896349668572244941195143856840032842195489553215406302254043947382368793914074147314353589439281000471813879502242851166670252197853998033813694814376228360691543987661407996785043637351295817024680721181205269262470473172181965930243852520386958529041036476807810647578694133804796395977642274699322030062940721165202488695975750512485574440928370802874677938542169620505668128224812441566912043326338714451629730522324228356364241376445033028898865300103247057378058702233150414643818049655628999871012383236520330575609745427181485617250755214922048672375947942288446974485524776744246517) + 8919329288393131657865865915729302254/882190226733374795594453383753215115233707780488511510968801361144824297271171040453030560721573997228198300463019014170354853929479983943317779570008135414645097864957897237942850344888515731013161186614310882299865065312281328425976427821628166844579546136898468399579307388420531509929375728344972058219238579923944345139420324610991005329112538579862919757599175513818412995957352856199020016311875104026207792481033655688345627471926791042717043753685205691775258996737590325911195399292216201069368214316711279213838705516528491500655825019669207328435019911314684352324150721804772331885386273726605701427307) + +(my-assert + (/ -8979365591106781219797187096315899769868799444656824967426553299158070014074001230883484015880186603742048949313393413640240595706939311540002219411120389 -1698360947072008877) + 1282766513015254459971026728045128538552685634950974995346650471308295716296285890126212002268598086248864135616199059091462942243848473077143174201588627/242622992438858411) + +(my-assert + (/ -12831814656788829919185319784994714617782749504716966706877579983082880759985031662545957372565411439648298939198657738497464024214657609856476819270030801 454910754379715) + -273017333123166594025219569893504566335803180951424823550586808150699590637979397075445901543944924247836147642524632733988596259886332124605889771702783/9678952220845) + +(my-assert + (/ -7834266257250691217409788323211914445703052638619784568844628449769010091330019095736167988675873769434766592786720961949649685040028101508217441360672222 -428418418877192732) + 3917133128625345608704894161605957222851526319309892284422314224884505045665009547868083994337936884717383296393360480974824842520014050754108720680336111/214209209438596366) + +(my-assert + (/ 5737805823029931079838944835405107564434908634489801628049345331760087020955028323378020396677249341204498685189403657652738071833877470777083253103936452 9588993061977446661) + 5737805823029931079838944835405107564434908634489801628049345331760087020955028323378020396677249341204498685189403657652738071833877470777083253103936452/9588993061977446661) + +(my-assert + (/ -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045 15760991890495426717) + -4001605821592542867351046644170905984672346731784670159062281252096012802838642896466582343641124674682428297533953704119505640938363392225910275838094045/15760991890495426717) + +(my-assert + (/ 2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499 -6788234478844960330) + -2876630161532936743269451364955814480771395635620140205538288339793482694260173239474830738010159518887660000673207712630507802368373928478641773477534499/6788234478844960330) + +(my-assert + (/ 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333 190237375887614033974333796608341639595) + 6230070442453337264527950102774203962152836811174649694700041895216739851602598854067104967963392074425258687296947909484969927078206601660837276754799333/190237375887614033974333796608341639595) + +(my-assert + (/ -12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472 -41681385674896602840749705069663453185) + 12098771374444180013224380531550204930654718468097503123335711776524055419889032578894177605164827523969169377266342179411916625188550162928371789854647472/41681385674896602840749705069663453185) + +(my-assert + (/ 13185465843955116174925558412278612918939024395488172088108029202384613698982949554556435640011161663974075894844304583900497170806796813871943782330552768 -155202352609947911537719051033334010254) + -6592732921977558087462779206139306459469512197744086044054014601192306849491474777278217820005580831987037947422152291950248585403398406935971891165276384/77601176304973955768859525516667005127) + +(my-assert + (/ 12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044 -249441012384365373362771955533424187237) + -12784980722915659825738808684740823452025110516624579136271791852138148426775553817114893299569867520414470532361018804123866264934222335562072872489963044/249441012384365373362771955533424187237) + +(my-assert + (/ 8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433 -23101645464137481399279134347982485126) + -8517839393030302736298983538193047531846908718502576675615969705563208303329257882565359266876007571790337440612227785062203468682754778416335180236967433/23101645464137481399279134347982485126) + +(my-assert + (/ -10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192 -25611473771508763579433379623726126173) + 10157767522292361462005308817460390811646115952647174687477824271227382383351453540195549992670001314693794150879368708343715654899952822395459036505947192/25611473771508763579433379623726126173) + +(my-assert + (/ -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974 5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627) + -8580252632668820290302987230726290672170301642399871646484841866604753910447257372311950907045477729554307803379310475132687855999835211879267570997069974/5347050029330174629945013741349819215851040371727058829687387719215168997632386672310746837193930669173408831178932364105722911104309540550576485594530627) + +(my-assert + (/ 7706102251141221799524762336156378964168657337573751909064577951085535246905735244239132983582998872001001594454632956803416956154262109939446710205558308 6334400709835247308796432875490978646658012545184955441452799118298109610816693049400832749087993843490999852355789914065232784070007399786089389453289854) + 3853051125570610899762381168078189482084328668786875954532288975542767623452867622119566491791499436000500797227316478401708478077131054969723355102779154/3167200354917623654398216437745489323329006272592477720726399559149054805408346524700416374543996921745499926177894957032616392035003699893044694726644927) + +(my-assert + (/ 12609622044672092190084693450911157599596799695538449568681964257744962273690941575572590166273187189250007688411096790312605666562908125521094386992971478 -8237858212652788898158635047388584411011830102060269605835391741772914864422465141467281143809161251942948659243584296367296559912373856433388249393853968) + -6304811022336046095042346725455578799798399847769224784340982128872481136845470787786295083136593594625003844205548395156302833281454062760547193496485739/4118929106326394449079317523694292205505915051030134802917695870886457432211232570733640571904580625971474329621792148183648279956186928216694124696926984) + +(my-assert + (/ -9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785 -1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086) + 9988492519236282081446302885464711911055350309732728352574982611126604133339499170845224383282665522673248920309221355720665956477799939031063172954469785/1878204914631111607000020160429571305542722711529281855381736226230242796648854769713662269068364131804626863789957256573308715572826753755672493154125086) + +(my-assert + (/ -10729942326579120947061030583094707809945059776287551713953926998992375520903658867971835616518813070294302895655369081976222497359056962112544408591462495 -4917625712783289245414023733273041940212797202855299465496072729329693853584860839801663152618595377553772371725021213143455497822882736730281253858119747) + 10729942326579120947061030583094707809945059776287551713953926998992375520903658867971835616518813070294302895655369081976222497359056962112544408591462495/4917625712783289245414023733273041940212797202855299465496072729329693853584860839801663152618595377553772371725021213143455497822882736730281253858119747) + +(my-assert + (/ 8114113595157517238445304590338354472776364877475201453112450680537221171989478096363668912966343706408770932684807802285529572133696646343108263717309148 5443953102973235688784499815692116502566847594605098596244123647428188581304528525010862185203718640610834003873728718183528722470626702382993497913086105) + 8114113595157517238445304590338354472776364877475201453112450680537221171989478096363668912966343706408770932684807802285529572133696646343108263717309148/5443953102973235688784499815692116502566847594605098596244123647428188581304528525010862185203718640610834003873728718183528722470626702382993497913086105) + +(my-assert + (/ -7125100205152691887479515774712530950031072786448635736036405923401522078562323494262148946679985384635556474075282302608446439950458673260234175964199684 -23871420315894180764743988478670341498770583257649869670486332228804693253344466615199983955886679924409910043885402198203427975742868174334723967563526738510726448815413356678504144193747696164586135745786501041060322480940451156015256191962506052700295351077719851275026974629635679531161390660244641370183176979934485671396035404817388717005746812037357500295693454623478902942336087760288091719793968445716246099043828787040340339906538864570506773535078524092440112404847904632624419421052178754041718790915772437556681684830937503838434712179830722395832238257078212535157309743054115702650740005055678387806081) + 7125100205152691887479515774712530950031072786448635736036405923401522078562323494262148946679985384635556474075282302608446439950458673260234175964199684/23871420315894180764743988478670341498770583257649869670486332228804693253344466615199983955886679924409910043885402198203427975742868174334723967563526738510726448815413356678504144193747696164586135745786501041060322480940451156015256191962506052700295351077719851275026974629635679531161390660244641370183176979934485671396035404817388717005746812037357500295693454623478902942336087760288091719793968445716246099043828787040340339906538864570506773535078524092440112404847904632624419421052178754041718790915772437556681684830937503838434712179830722395832238257078212535157309743054115702650740005055678387806081) + +(my-assert + (/ 4801495919363827077158204249631885157347198552733998896638174958434968555935827788499392382851493568264006507028024783408190862186734863708684652212703744 29234959990138609668202089052356468732793041824333219340488007351402997202222578434579705387840772390513345507274006495462445058795870182760749392281528881636623188890883479914921272700981309656920982410970774047916714087713562927554033500521877735827036675598267184309367127514966388636440710253467328441763131873309183205727440365838789320851968108312559316922678357314418486932673434031479515016224407618177089903730349114511598373251388750023508633761000320088841886505077453257141723747388913336375142897897501529451618927178835485127020789481918641637409265186365292847057986276062625965612268181771076051892980) + 1200373979840956769289551062407971289336799638183499724159543739608742138983956947124848095712873392066001626757006195852047715546683715927171163053175936/7308739997534652417050522263089117183198260456083304835122001837850749300555644608644926346960193097628336376818501623865611264698967545690187348070382220409155797222720869978730318175245327414230245602742693511979178521928390731888508375130469433956759168899566796077341781878741597159110177563366832110440782968327295801431860091459697330212992027078139829230669589328604621733168358507869878754056101904544272475932587278627899593312847187505877158440250080022210471626269363314285430936847228334093785724474375382362904731794708871281755197370479660409352316296591323211764496569015656491403067045442769012973245) + +(my-assert + (/ 10769619761532897875307527770350128978615798426116103116325434914975512103385205123955114305107607195469345895102375220593168903042839441996791318999499708 -7224105715967976893083374742254251507019823877014718307738328810406361200631626366722837314776666720638271529652546975342143108973422364041422652163016078890272393678677152791565494865444430757858556891645947268886646732022748338160528677218733159766121781240328812893374941548395710123982510227501927393735585082736583984561348450061452997663109932611188779299623613963995350679177776686423432406091192517292522853783968685873925548901506191291253596763183277703635837071862492572256145656312023955675669362656148946145528559574994353884313568526553663370513565393821926602014407548325293145102073923450066319746913) + -10769619761532897875307527770350128978615798426116103116325434914975512103385205123955114305107607195469345895102375220593168903042839441996791318999499708/7224105715967976893083374742254251507019823877014718307738328810406361200631626366722837314776666720638271529652546975342143108973422364041422652163016078890272393678677152791565494865444430757858556891645947268886646732022748338160528677218733159766121781240328812893374941548395710123982510227501927393735585082736583984561348450061452997663109932611188779299623613963995350679177776686423432406091192517292522853783968685873925548901506191291253596763183277703635837071862492572256145656312023955675669362656148946145528559574994353884313568526553663370513565393821926602014407548325293145102073923450066319746913) + +(my-assert + (/ 1505915608160301518246681692927442986955390537144107830770082927276722640395785957392652130911646706470337068266772174699405268120590454296080828168261019 31152879253507543898583880698200027990847289346701738353567402100527465991154555548630544962150902011282973749886327325250084401181379196961322399337408341296727915922288276602390334861175305055229766353672502691855637668618950047400571070157436221479289152631256433294884836727331457389922838951144187501751190662594278336543502171639899940796536926507796271202659224890656712231014450702948847764643603683153113663072089256293587951842007583210791100743318865647555912543508324790181772321217524164822106191538518498016236866957803105254555578252294418243701672226181762763332992886540089416888889135117147250495261) + 1505915608160301518246681692927442986955390537144107830770082927276722640395785957392652130911646706470337068266772174699405268120590454296080828168261019/31152879253507543898583880698200027990847289346701738353567402100527465991154555548630544962150902011282973749886327325250084401181379196961322399337408341296727915922288276602390334861175305055229766353672502691855637668618950047400571070157436221479289152631256433294884836727331457389922838951144187501751190662594278336543502171639899940796536926507796271202659224890656712231014450702948847764643603683153113663072089256293587951842007583210791100743318865647555912543508324790181772321217524164822106191538518498016236866957803105254555578252294418243701672226181762763332992886540089416888889135117147250495261) + +(my-assert + (/ -4912349668310730778272626761660101328812783790262451913449395750351147048676353891314609774894027305081515542385381430403698808605768281804457186380542764 6582102431028556562269167182029950958541569095123705594954788174046339660437206159173417583841743892857066740116322758515837624700881569925244230209567223461401193316695082415261197843574563450002486582967745135870782254839990479649574452750850133306720341823136645982650022199634379361313745598455049448887744206616434903460504591098363901961758069797933831934878649993183747273660007900662110776570580293994733189753806312784239743585453090900671308673380802381312083077891736513388250097195232616017027333586286786139736783210630705878401429301217589001317082952461701571026008195534878902572422952568763551674434) + -2456174834155365389136313380830050664406391895131225956724697875175573524338176945657304887447013652540757771192690715201849404302884140902228593190271382/3291051215514278281134583591014975479270784547561852797477394087023169830218603079586708791920871946428533370058161379257918812350440784962622115104783611730700596658347541207630598921787281725001243291483872567935391127419995239824787226375425066653360170911568322991325011099817189680656872799227524724443872103308217451730252295549181950980879034898966915967439324996591873636830003950331055388285290146997366594876903156392119871792726545450335654336690401190656041538945868256694125048597616308008513666793143393069868391605315352939200714650608794500658541476230850785513004097767439451286211476284381775837217) + +(my-assert + (/ -11503235648135220410087372678575470255397243144180272745183844970864347348074104828328211521698012119761674096067066173927209129755062269068090560678650614 -5548338218081690289723998288742945948643693817491921699797822887914665364835947234564530865119623677435878746610856459141463506776423054050179729345956931675338102809929977610828639446535095411122377961067651902947030310564736893080382424590568134091858634304377553326990788802662029347894499019277621467098333287442862683493159356014650672092060912274570436879076161496563079759704321556494898013269338428360856068237785049960484767969682269790642298701577934519452927652996671267126348627432295779183359417597868330923329974640383630473044712419371517153268338860560601603043892503067815822312755611206254762903436) + 5751617824067610205043686339287735127698621572090136372591922485432173674037052414164105760849006059880837048033533086963604564877531134534045280339325307/2774169109040845144861999144371472974321846908745960849898911443957332682417973617282265432559811838717939373305428229570731753388211527025089864672978465837669051404964988805414319723267547705561188980533825951473515155282368446540191212295284067045929317152188776663495394401331014673947249509638810733549166643721431341746579678007325336046030456137285218439538080748281539879852160778247449006634669214180428034118892524980242383984841134895321149350788967259726463826498335633563174313716147889591679708798934165461664987320191815236522356209685758576634169430280300801521946251533907911156377805603127381451718) + +(my-assert + (/ -22964048032108117904633365483799091488990853392670636861794813863757795874434768543212887316456319246155824842161717179767513360050328383696194174741889496306018655333450647372293193335577883672679165775070112770359697627614883420620410888137853011387271594559450892054491963940112235887802995117234918878648066362268919389271696465517050425727202664230530633207566444357393843669758809938086228366322548799235049875711702216182219182908217345405023677260470015666831191434586902791186444958476491096759363292487221288620810273243009200212776634572092195691654105986099646006756823055390654876878195583529521482548988 10644501761877612307) + -22964048032108117904633365483799091488990853392670636861794813863757795874434768543212887316456319246155824842161717179767513360050328383696194174741889496306018655333450647372293193335577883672679165775070112770359697627614883420620410888137853011387271594559450892054491963940112235887802995117234918878648066362268919389271696465517050425727202664230530633207566444357393843669758809938086228366322548799235049875711702216182219182908217345405023677260470015666831191434586902791186444958476491096759363292487221288620810273243009200212776634572092195691654105986099646006756823055390654876878195583529521482548988/10644501761877612307) + +(my-assert + (/ -19058897134776675884737764093896349427183484738023061956638485191239529906311503740032626797095131123523175909943402828257449376045336777553758951620699386266853663342003969442142858702229701661125904623724248177901462857013835790939020450746503125344631958534655024089231193396521561965297735217497608287565163852923704017958259400904834287026933197193592591423799328167149965328232560408884408251535373934831244856695227539243433290481951528897142697352526450162440279318507285454432916819060795455956931254810171588139618689138022062041222735056137988435900866680084665165131313435515187611756148824388549448126467 -8326067459929079652) + 19058897134776675884737764093896349427183484738023061956638485191239529906311503740032626797095131123523175909943402828257449376045336777553758951620699386266853663342003969442142858702229701661125904623724248177901462857013835790939020450746503125344631958534655024089231193396521561965297735217497608287565163852923704017958259400904834287026933197193592591423799328167149965328232560408884408251535373934831244856695227539243433290481951528897142697352526450162440279318507285454432916819060795455956931254810171588139618689138022062041222735056137988435900866680084665165131313435515187611756148824388549448126467/8326067459929079652) + +(my-assert + (/ 25828007361450952719858846443651616751980622231808382804245407702688699228397920589229449608543284896555585501243582045708656531815385828908740757435341854996277769645696261182122648194952548457487178342682313459444433667556195761154944956714756269417591048771194019245925463541886773351873002480266654825771525233808830260734678788520487541379982691221386179066818743751876186761036101255542680066874888848011074569355779905086056095043888696435054884292698783753890317487209955316141370052511469715869816445031102161253514609763532756500340262263800747279044587806090353812452308490155782240390040070679663451429071 -16419739031141199968) + -25828007361450952719858846443651616751980622231808382804245407702688699228397920589229449608543284896555585501243582045708656531815385828908740757435341854996277769645696261182122648194952548457487178342682313459444433667556195761154944956714756269417591048771194019245925463541886773351873002480266654825771525233808830260734678788520487541379982691221386179066818743751876186761036101255542680066874888848011074569355779905086056095043888696435054884292698783753890317487209955316141370052511469715869816445031102161253514609763532756500340262263800747279044587806090353812452308490155782240390040070679663451429071/16419739031141199968) + +(my-assert + (/ -1669696848499325185991294008037906453080648048592518700324899343297324898656645662186964240087582483813312797482298159224575128489696846451225871663856944749639170892311973606684486632224811435175199158920841554176114937196187087530038509898368755036744105403511353564606301040888877621412514452110348953863172547944175251415725815533087344857665837809749724257466399374547882097484009980477192931829030533366309859182367479867549644502538060694266048652224732348150866071381652452605392696555259221463464108413747443898588713629829490175098280805280460168541344102200890646453100478450456898359263676257882174308268 -3154577849943484396) + 417424212124831296497823502009476613270162012148129675081224835824331224664161415546741060021895620953328199370574539806143782122424211612806467915964236187409792723077993401671121658056202858793799789730210388544028734299046771882509627474592188759186026350877838391151575260222219405353128613027587238465793136986043812853931453883271836214416459452437431064366599843636970524371002495119298232957257633341577464795591869966887411125634515173566512163056183087037716517845413113151348174138814805365866027103436860974647178407457372543774570201320115042135336025550222661613275119612614224589815919064470543577067/788644462485871099) + +(my-assert + (/ -2215504974719141921873290809898041836016933916943403987778356628123168736190963062169230280020568365292362281642280014010817115943641228422541948070912910166283758843455538187697141038676028739959626556519808411324617157646799936128314485433146912658200236754847332237438334421065771940922444296618134121662770699950019164632463150784605652351782139277998735272280336096528241168196650073301607171613955878761317417480490869592669781417658461696905996344800864447403426286476662235990122025654999230690604488053668524888833992415515434190712628587043474760836969696399229242018051635699746048823240033842587927229964 -11305319675542865070) + 1107752487359570960936645404949020918008466958471701993889178314061584368095481531084615140010284182646181140821140007005408557971820614211270974035456455083141879421727769093848570519338014369979813278259904205662308578823399968064157242716573456329100118377423666118719167210532885970461222148309067060831385349975009582316231575392302826175891069638999367636140168048264120584098325036650803585806977939380658708740245434796334890708829230848452998172400432223701713143238331117995061012827499615345302244026834262444416996207757717095356314293521737380418484848199614621009025817849873024411620016921293963614982/5652659837771432535) + +(my-assert + (/ 24358677073350645219370308521851912760304925518671532565724702185818845784332554892130070740233218685874351979772556877899278790031132507391155876157108663291716896413773711734271947599485714147026138105714458778787734198938526335256418673319464023475137997251085298903419563039860433435847755093653670989129405749785476487449599232956305952768800154351414655365461746574761818724131185410194605648466196476174400166047788352670171627261342369793028465418799251589432585363577887467959594667618177199696618852093807640490831859585621198048572586882398004957371434677752931134884039120875470266936204172511104679441462 8754800987327220648) + 12179338536675322609685154260925956380152462759335766282862351092909422892166277446065035370116609342937175989886278438949639395015566253695577938078554331645858448206886855867135973799742857073513069052857229389393867099469263167628209336659732011737568998625542649451709781519930216717923877546826835494564702874892738243724799616478152976384400077175707327682730873287380909362065592705097302824233098238087200083023894176335085813630671184896514232709399625794716292681788943733979797333809088599848309426046903820245415929792810599024286293441199002478685717338876465567442019560437735133468102086255552339720731/4377400493663610324) + +(my-assert + (/ -26302114071841994464108666310942614602208671348774320769941579409198660404735714925432808094014718434192516800374483192192707032773903982752997957629389083405320034044554226640590549491188742685901503166669355807243735533977994184111229208270447279559478659750835531593667003322059717930484363943660175452777363121025595100592911646539549735930625865256846706785601753749996181113742254145758187876411260965175520035400453360390392991183382425735199046574346992179663247011131958270717402007532256308394559029768974932620173103778338779940189812875680687510582798628982957687329572431433891809534332514765287899172737 196971971351558855568201373145365478995) + -26302114071841994464108666310942614602208671348774320769941579409198660404735714925432808094014718434192516800374483192192707032773903982752997957629389083405320034044554226640590549491188742685901503166669355807243735533977994184111229208270447279559478659750835531593667003322059717930484363943660175452777363121025595100592911646539549735930625865256846706785601753749996181113742254145758187876411260965175520035400453360390392991183382425735199046574346992179663247011131958270717402007532256308394559029768974932620173103778338779940189812875680687510582798628982957687329572431433891809534332514765287899172737/196971971351558855568201373145365478995) + +(my-assert + (/ -25700334917103749626396366612061842558162882395534131493737229591609654899446089376271023701490708870843231350129849819430092002268875830384992877382393956173037794109904701961390126146975281052960293513473777226100954163054292968509501976296424278813632162404905591038465215586347229260479401862039805429711982871702185657527199220459658257385112793877259572278229045135617281858788415643567614198333459934599272409406206213115625226065750113120833933806486512117533453281522448845990642550827848765145774541658722594353290694745164913189694785762218575339370800538946514325662656804799046877175035545715523049884960 56325873113907570153638933263921340484) + -6425083729275937406599091653015460639540720598883532873434307397902413724861522344067755925372677217710807837532462454857523000567218957596248219345598489043259448527476175490347531536743820263240073378368444306525238540763573242127375494074106069703408040601226397759616303896586807315119850465509951357427995717925546414381799805114914564346278198469314893069557261283904320464697103910891903549583364983649818102351551553278906306516437528280208483451621628029383363320380612211497660637706962191286443635414680648588322673686291228297423696440554643834842700134736628581415664201199761719293758886428880762471240/14081468278476892538409733315980335121) + +(my-assert + (/ -25716495567761925495340309269248196976121711927176026606462843116646034561721958499564011513233986043633061335866265799467020807570689498961190839877265773450484494789052182300993137822542881883769593344810286970036960228835955266304979090841345697560418139960733748874044680214388098802745248923989851173047158103142988835055585349795022662576576434371181693607267864646932929998659458265265400181839509356921460222604661909947838434113964465769102604033848276159366897885013231683417270877512514679528402888899725431524867260144325739317224922955028035417867933390409466302057857579158202739536568407090965929352402 -92089830031261826185903006947297196357) + 25716495567761925495340309269248196976121711927176026606462843116646034561721958499564011513233986043633061335866265799467020807570689498961190839877265773450484494789052182300993137822542881883769593344810286970036960228835955266304979090841345697560418139960733748874044680214388098802745248923989851173047158103142988835055585349795022662576576434371181693607267864646932929998659458265265400181839509356921460222604661909947838434113964465769102604033848276159366897885013231683417270877512514679528402888899725431524867260144325739317224922955028035417867933390409466302057857579158202739536568407090965929352402/92089830031261826185903006947297196357) + +(my-assert + (/ 6427758281007308443295844679532867042370757542760390680622584758338041709910068192973790897624827722686313216884084305612889554116246627679267186323854642904894988936981064543865794245002470271142875081223308666588659587718561791667575945670118263124267218395749059879636505504607358472659126298770422135028955713148882314050530771750859372048576074912599265823577267962213046012777760882389021047579367276198483178024744924299929585515193595330026399302022065656106472153858484998010254767462854235008343139218888170221421046454280858208068658907389288543063912721882521711363713136166478126504226820360347652405439 80854661163518168674595213426641201760) + 6427758281007308443295844679532867042370757542760390680622584758338041709910068192973790897624827722686313216884084305612889554116246627679267186323854642904894988936981064543865794245002470271142875081223308666588659587718561791667575945670118263124267218395749059879636505504607358472659126298770422135028955713148882314050530771750859372048576074912599265823577267962213046012777760882389021047579367276198483178024744924299929585515193595330026399302022065656106472153858484998010254767462854235008343139218888170221421046454280858208068658907389288543063912721882521711363713136166478126504226820360347652405439/80854661163518168674595213426641201760) + +(my-assert + (/ 1960728263483597985471065015024594804771170333646104429205729831998416939777820080209106943861368202560376682136488253096512360698625765514606930980274938979705620987031595592685578710084284618125325617453699875318678007463857705931376750632972266553809944621631324385690517092215690694024807784270742388108802858889381036105223858467345514041786882957807868961085072340965930749117411726729713477739990680381647988935514765113077094375924848051541167125595015542791382355149166582367766443782842193396221676952668624805183924877889696428989259842153378327156342464279071638070457876940165186524833987190050817072048 91266493124541431873557009470479491083) + 1960728263483597985471065015024594804771170333646104429205729831998416939777820080209106943861368202560376682136488253096512360698625765514606930980274938979705620987031595592685578710084284618125325617453699875318678007463857705931376750632972266553809944621631324385690517092215690694024807784270742388108802858889381036105223858467345514041786882957807868961085072340965930749117411726729713477739990680381647988935514765113077094375924848051541167125595015542791382355149166582367766443782842193396221676952668624805183924877889696428989259842153378327156342464279071638070457876940165186524833987190050817072048/91266493124541431873557009470479491083) + +(my-assert + (/ 4941680418946960910262990974014623728051861920391294141439502190044830922127013115391726343950340163023958511659132792063033185693862678433421115681422259770928656196358763089894449447854011668445981430826871764812047994423858851467292757304285634515474652989618200442851239459073981986390515468331839802701176644729973346052528164203299481240263263697394061787580128379398464090163611942724580936445878570184925290925246112514015572149640886198984723311273144361235138411362294735799814160816806773736605477503201836095726740734281001021071803299510239436683913500734680524381145064985356627091311888606290704759943 291575320383555320391938911470370670502) + 1647226806315653636754330324671541242683953973463764713813167396681610307375671038463908781316780054341319503886377597354344395231287559477807038560474086590309552065452921029964816482618003889481993810275623921604015998141286283822430919101428544838491550996539400147617079819691327328796838489443946600900392214909991115350842721401099827080087754565798020595860042793132821363387870647574860312148626190061641763641748704171338524049880295399661574437091048120411712803787431578599938053605602257912201825834400612031908913578093667007023934433170079812227971166911560174793715021661785542363770629535430234919981/97191773461185106797312970490123556834) + +(my-assert + (/ -17803449239532304707372697093467431202778585961066204978641168716990033159088600623106396534094218402005803618121159982050197012697237961155375180768349707725936023283589475384693590539312637333226292265409814019687105755522332846972859860649558844229320481883408457674560284773922666633054564243260924189551494368660033292970122831009582038986061326503238023206238467592238752824663935316307653075615249537594229930297642710570473007696494702367783692850946455203144153509057520651038068881755863521371187245025834292163874467913915588768778393773565536027848586260129438664753479013894698439967637389690509120223682 -10962227285754340409566802000064407225866105372406170304563353147415988225079632767886653994299800743521362563345682593189107807948342418743229049299449088) + 8901724619766152353686348546733715601389292980533102489320584358495016579544300311553198267047109201002901809060579991025098506348618980577687590384174853862968011641794737692346795269656318666613146132704907009843552877761166423486429930324779422114660240941704228837280142386961333316527282121630462094775747184330016646485061415504791019493030663251619011603119233796119376412331967658153826537807624768797114965148821355285236503848247351183891846425473227601572076754528760325519034440877931760685593622512917146081937233956957794384389196886782768013924293130064719332376739506947349219983818694845254560111841/5481113642877170204783401000032203612933052686203085152281676573707994112539816383943326997149900371760681281672841296594553903974171209371614524649724544) + +(my-assert + (/ -11349783565099575757929584771389010505157850113880084607145768380886038854233583951229136273631022011781914171912628263930864052254964518914857757025547156428098062812984733912827827545722979442676567330004437902674729872754963478834939047061999292143602525229120558979819117729589695377623970606315287270030693151486803968345724658003068961239204812937084581894755863859944500186226990319892122692007317326534880413455575446314965159569830188583093978564829748603480193166063624130610256395632946002879039047154077629561745862713628266069928068634042545592328263646730943717246953000457159714049930890865576634096206 -5169948998417532948043886408019867395123131165917923418040862036041756675786217242743410895008311710518018466892169868028617239526646914529999134517417939) + 11349783565099575757929584771389010505157850113880084607145768380886038854233583951229136273631022011781914171912628263930864052254964518914857757025547156428098062812984733912827827545722979442676567330004437902674729872754963478834939047061999292143602525229120558979819117729589695377623970606315287270030693151486803968345724658003068961239204812937084581894755863859944500186226990319892122692007317326534880413455575446314965159569830188583093978564829748603480193166063624130610256395632946002879039047154077629561745862713628266069928068634042545592328263646730943717246953000457159714049930890865576634096206/5169948998417532948043886408019867395123131165917923418040862036041756675786217242743410895008311710518018466892169868028617239526646914529999134517417939) + +(my-assert + (/ -4372008041495429462966226028389793326873997497126815043214338280101332483009650104005998792061125254101227371430911497751865710691604158789733634394053254604723940088324934622768312096370232736965692181452463495731681105253628558429524788376108667441329817524961077744083376843098018692898745743361309486938506049017980865957895278210133305721083115513131884239744064081819033733041876411992332060293539102545847193260167588667810376670587099064558298380310132769718526554738650709745767046942440481512965138461694790645096012018276362849398785863823724642554436182185786302301222529261914437437947741031113015699315 -13213007132248918651858333568248204618745148942720942572088217188768868803339938910599097839075045781852237705726227293430250507070717570662238736211897310) + 874401608299085892593245205677958665374799499425363008642867656020266496601930020801199758412225050820245474286182299550373142138320831757946726878810650920944788017664986924553662419274046547393138436290492699146336221050725711685904957675221733488265963504992215548816675368619603738579749148672261897387701209803596173191579055642026661144216623102626376847948812816363806746608375282398466412058707820509169438652033517733562075334117419812911659676062026553943705310947730141949153409388488096302593027692338958129019202403655272569879757172764744928510887236437157260460244505852382887487589548206222603139863/2642601426449783730371666713649640923749029788544188514417643437753773760667987782119819567815009156370447541145245458686050101414143514132447747242379462) + +(my-assert + (/ -24003371850945507239307096734506644624830254935119140199726507920301383328662376914775504920527918338079792692943250446679097229950654636321252144129692109999375967030689211646504258922323499994340282315270808545865248969923421472430657741998787024263629527291510416193284540865950122841477102934165296344839654902079279846705581902668360663987722715177845485423354226653585575109653937253382583158263755381721094429734122004436184054214443676096492583897635497699417294183504529284810360226314491839533303380490277211336049582128602304906849999737224506976061216780230350942535246958957024226614847691329767208211525 10686139440491678930358521446524488461285005495304677740436234635584738003880529034339295291091217655777627375148264449580064000634364863951333061091724053) + -1263335360576079328384584038658244453938434470269428431564553048436914912034861942882921311606732544109462773312802655088373538418455507174802744427878532105230314054246800612973908364332815789175804332382674133992907840522285340654245144315725632855980501436395285062804449519260532781130373838640278754991560784319962097195030626456229508630932774483044499232808117192293977637350207223862241218855987125353741812091269579180851792327075982952446978099875552510495647062289712067621597906648131149449121230552119853228213135901505384468781578933538131946108485093696334260133434050471422327716570931122619326747975/562428391604825206860974812974973076909737131331825144233486033451828315993712054438910278478485139777769861849908655241056000033387624418491213741669687) + +(my-assert + (/ 11114571678097117920369007866358540243142633567044843952020632081573546909920632543585596494530749645890342978505657174505155646987551523455565703297238406590291026899487431109110746657023874064284362499621762851387854720746040865741433394111425240861542892218169985953747711593827913014379823797703717216676877313898809377467394109623799717556800777662963842899812297087284510893865429864819927951428138755600792987191034272014681606301885821862650098620488569288170357746018556395309910262410994899971436293672676949544989196526035130226777567220128838888396668158456237490064462262193759918857287915854681904206680 4808076329737968688023887165061921594706561818755147855784713748545995818001333418509444774306288638038607173052166709335820929501845348060033808100812677) + 11114571678097117920369007866358540243142633567044843952020632081573546909920632543585596494530749645890342978505657174505155646987551523455565703297238406590291026899487431109110746657023874064284362499621762851387854720746040865741433394111425240861542892218169985953747711593827913014379823797703717216676877313898809377467394109623799717556800777662963842899812297087284510893865429864819927951428138755600792987191034272014681606301885821862650098620488569288170357746018556395309910262410994899971436293672676949544989196526035130226777567220128838888396668158456237490064462262193759918857287915854681904206680/4808076329737968688023887165061921594706561818755147855784713748545995818001333418509444774306288638038607173052166709335820929501845348060033808100812677) + +(my-assert + (/ -27971792815424016824370019866875377333122266892537700816201893161065327053508379094007350664178576160161460501442627646041422270472469587140689725524176629653056006769618104516779694726446739085332330345789012312708713495757968594985567285237456431009983022526625885024663335598317191838389804118084831445251467492693688286258834282078888862754754572546522075833632779922232880101875914894393005204887265821991459415144492487189071888581048779385051174007698853920104709378859053075296413813207007405843448595681090932498329066591349910723578718333092115184652723310842559914379989208301125396793101430807658654849482 3169580893680227534064172567436590084742349042688765883461923377455374714865282199177755353861979892274552092801376364846717140845237173266602633583445110) + -4661965469237336137395003311145896222187044482089616802700315526844221175584729849001225110696429360026910083573771274340237045078744931190114954254029438275509334461603017419463282454407789847555388390964835385451452249292994765830927880872909405168330503754437647504110555933052865306398300686347471907541911248782281381043139047013148143792459095424420345972272129987038813350312652482398834200814544303665243235857415414531511981430174796564175195667949808986684118229809842179216068968867834567640574765946848488749721511098558318453929786388848685864108787218473759985729998201383520899465516905134609775808247/528263482280037922344028761239431680790391507114794313910320562909229119144213699862959225643663315379092015466896060807786190140872862211100438930574185) + +(my-assert + (/ -138888658164471549506154385143989713534453638138516110941977029 48484067562152384719540184707188444570280914254129306788137384972303743285284814 56428088099244342456240635263153370817851703737803685168591843059886944388583310 6984617762898435035101945891920384937438416626357047934508608980105797822504000 90193136183227859939744547239819443586783276313678017953708293432043879247302040 70539472782976230144489157899475475029273447055080677052149474853222128626227832 2525164589393997980217929709704832829968554364529060039097810436136432713906553063644429644328565051224269893261942396763235990073001625976866246420775436 15614337547041181126817477188043219628044963126229393225781917631975649438502836750353253851523795212263078850399716875892512719059737913422781999218667136371648316387382440793865460028660248325297931269646982047533754121791358966254514009830876592200454797694143082163294323565673200905929297174223061890100210054105027025488322289599106119653451218493916291922340123640475500240519924011764050880374885136181582395113140580448936759383024305870622004464940344826337458060607492042593813585998516868215921180540240201095202617277388950504036371411600204964284568597705251929695275183521036281637399204541958859605054) + -138888658164471549506154385143989713534453638138516110941977029/4793535847709521198063287553243915170068914691727215964454867625024011698922303669226389748584276840530192157568469968220857898703102351955898913589325705637953049380748829567692600765708909637920797057370082064005557328769108356548100875674196976079597658854339583183901899349355521527519781721778545444496852540362424465770767219571362842157786846795990148969989617793004579188905882473140017509154008696803103206996067638134383708975696867028865870695941933200225325283190379262695816923376790224594063264297952504481719779782130509306530621779762254864669078635401870023086312919956154224782043667754741333688780367667466505233610011253346902821033707597517691608103391952937194719540981992469020284583499872663129517095879706480339710037976698298522952071766717472040399518290905103777436461474880898550115925718887748413534479076504168236430697214654069473800915087572730747027455509241250627470590715812698745630545585772046458363388764449879417348554556621640336029897762172500880501074103433267444717053504878282494505367980026597725927414511391047010801407870379019921551218005714825277162504166028680939100225793768617321830389705750902850499916610355200000) + +(my-assert + (/ 2902267908619179684129536324641634394442732593027015198805855082 4748067699021154152763168285921806700655154833226062437593302484475663167752990 92172802787151156076284963978247829387076983213530315481815585776147505007251090 15808981285029107672090190966349736198141855760941720122983980047623201110025085 60559202289239963744584432021634662330089323842876293477363484160210450706125345 20641717016962556495214267565148984505293698026059157698737040675346468206231142 142380249473014630955299439077662853963947100833592874440361316474000948841420058017600161066408668117933232436922811486348705081331372574460204309908598 22418721268614574393232189860262616514600143215945007038687873335656746730488694050883006164427390756358558140145027011322151188565843290717535647848841274550496431839061217253488169143292339455650565906288959125935798633464526818546688779845699340483771625364583343140648892889571715648295855169294054985996834093294240640072029711789359793649773566295329912082241637482772608479106201840565936084243727069954911883243252762742415647868355726139789907900798435783365130277592703989608678774745914668128791639635886550753850811717805962562157686110637810320436812644047534536168343578232389700410352900247092236175044) + 1451133954309589842064768162320817197221366296513507599402927541/13803211377640454778526029288269623376813125655593684775595099045285713415153039020789267800416616529908688645478733023490751981264976732618374046330204398361829051480928696426688037404239513603403603849882719851670264413777889524531938606364925013854252374108222701436535488401321603495905123597139234414735397259257280679663147039651553472142280954446675036289021783142392760217244908768132158498744301278889276778209560846418263599491357632762902447742083022806085077053406738681250354036208472026046315736408632370478801849290705001622808552373129971427533249307210975612625050706661691322027927380443494854794852235813844542319971019369687589916047377092369702778251658652143114091304960406840026816351348391618676357634544120732441610431417230403811846208113160343697557236265319994702483700922393762500190362776377442551539417224595247790865885105594005740401824824367904020732469833438717527758468635665777261969819260766044978137909489986407113029460354144391595512642835261443393260585888868936164331461486646676578398836326366036777321522851855085808626766493197635871100152761464712744017549919220291986785134521319127277292845352756807452050073157340000) + +(my-assert + (/ 7798204144688205291220879078360728451593323170355809361079096742 35808393784851478122520372074317359817820799318259895240196875729073154197251420 58532175726063855694248618287185551673975962776708803423334853085996022345828434 97834368697888769536063057370864051207348099191057106781292664602519775900739777 92489021460656714290092899983209031746574776013841975324837145038810562509209529 71083733375588666647468985607775761710974844539643116636307037921671845148256816 6123989271760127932230015643359630675168106436173654465119508990415235040641894537960236511442249258231302028977221206744158863083898145166446430168108 -27418900206398855942064397259705713102524342707255992250395147550519659429645343464288092288218160406382406024735131578979728501208163782063519839258876833755387025755815673514708453862847139552613587001235204464673999898312854941659541050445981594990466469147364579547089805525464252876345032296745312923488525701877655352034887018931755379078328147999631937419977103372927428613463482328465834563846802083044643719319690088670748858904291298575733560600669924511028715689681303059001186388754140003746463568171428267337107394361025465082282061651196456268663181772211292647101192148287507051053367729008997838464209) + -3899102072344102645610439539180364225796661585177904680539548371/113184205287561573324139833190653102440730360395399197973956984769580868365256138025034414373155098575475566747215877030265786675432252675717351889433714136838615056208470421665419618669892136317438270826178251174708190860235979949204785938786562420189510825909814566675745650194525647207897976611434325225523578368855952217879373499055292850828774005130267218801086474623429504045290678320168493275019256514768273116059350700654655821674309331585233552793659038912697151359657915391954687630783641745610431060563252789714638916120291482852533638921356624929690158752601417722733222880768367060672103351737811624242610815140332559619520810810999145535251960674284283045907801934328911198563750515779896457101601178888594882087326241517566336011980952110586199881600553269825310575512911473547251704677890770772166895623118832621335417348044312911888377718725944255218219811801447500167145561774582342171995333086224230231746597452848775656030037837271428187450747141983599129861631612369300880722326218963779650411119279310045263996988089484063433088077868691314162108392639864773907107325220582413508233901954483499166402135445110435112499264825479433389003494762240) + +(my-assert + (/ 6291885367078853457481986049409245691302078375827782321496819120 20959289231548357352292073342856567687394126070322865796282035211176720583560298 24366038587110130209541647226271577368736240640393242419005751016119649778306566 40118119174220166901790237425673316895032570534639145502274313654443256239236466 73598137358602854818844747625643480865061277528564461120022408463105339470504117 36695182446520138181079917512512743290981469731336486456411609014364293489978544 8671667981598505073194269824535189054936442262459158402875147736469644925300845122881093216273840895555488593258562684601176239455526568314028830532770 15920064019095473156324398162334173238735268739049399738654357508344572552411935473846021991360836375685872129737682603096450566258725052013769725919038955505690389573813769125933987978360857342250911865713011888064725725934341157729878064563080803955584985269499994186472079783942404183377695242296289152788154908185130552013951432753148997632323578507137074131845177376689609114975253308906745794984371839952312988353950198030866538756253618535421214253194954603293145507537939731320546686208032528588232652963255550963088571344119439249328480867640436815434047309164687808223851012490130534705427647158409623238123) + 1439421788255379275215959765325419043929720157723371200401/1747562187028503746686299553853635643553063923188506902759251937250022196751705340155682655202720363192751787186892107863159676381018035068965958466119538181810433273947829904580526582292369320932134048728374142501965682147541817431447933591106030690334465450755701191781243754499216697336293783127396687916725975251100500896467549458036395977769801208905203001097425041200299917628353220804629035768571072498715030261324138691471497255335498185741379289492513543474304524261634247519034231348033379344777678679950561777846684978640375273167561174451700942154388980887510088060818147834369595669846115248027925007288445161871535514130090907585140894883683709507099726386549038354860875469377442908932714711235823032704493155679240378374325069782368108779247450762222838197717507164088182062062215767468125843278459189085290703729281279344184417197883359351058003644499215541300350121854220342250451978930421772367851329849662028719768708399155817754711362398236471946313773603716759409265530444582884661320404389499624411965234669344882203618613097197387901166904575791500958722726774956950592290330175936039556139052663816485140080963740296685158607671768592) + +(my-assert + (/ 7377598052472799909620353419322603137723415431070641423056433630 50990728761110292768803869421408199244526424730838143228662194914314857136430737 89434155113971221138805303763480423496687322824531744020762041598590716339098287 91343386111124700155689622654961840380754244946720984970313893805578518003516073 5641075230099727784981579696383316732450130418277879081291954534985607255267932 91040802121912074401640073226003257602385910518707524375098380810792151468159323 59272268188012925764499414539835790113036863511169317924034366016920114706179376837448098952655862721652129333873020625135398431500899131874782270590048 26690053756452308398721390096804652429111408747235998849320348549870126230712525274708597346508961935323823048352116439255386668122483555236157562141222434006899926132549352821247340442387991613448730451171206857242290791156220288682675982609964518905569737166444127835826079348146626921864776959482079234994631361894786436656768739968380067890165160954836874044821979903056957225885565092422439358816023307475581832942250031121721325840673134241504501661692722633100336840768527354183989544434614842654682324213774503456414914613412547380720171088896588158750436205804689590730033393056191028424154915201435563063992) + 3688799026236399954810176709661301568861707715535320711528216815/169215718032454146095901737002485678790901914179482864125777331106759302744215797822810809511498045518338288799757661725047129775976254373463314416017128993811694804386237923340900604770406784566473173755998386770282409830097844352035251738093305402541509197084964701114515390028814839744480965823142680384744649624767291550851759670297818996073873968006960956353033659153219390871979066743795530136868490210455800714335529013059123604101460242870160400211866883478263106349349114199154533363251799944090298252763172390952446660627602934622584400932001701907172000401485323481964448487312714644861543740014645407417493588261100128985848137181719614326345024112347151970444057551896842474702539258687521054961314443551837168457190568932765925484427579811571491887599619302241390226818415165012748654917331557679228501007751078584244340346651276906088856205294333241792044902850102153793417101337667969641035858108457362954650972654353600494166650067557014544136240962457086782865870886529792004619668808741311540795514394731398977642092124679638585188974746423756335151669217754388004341907440529525288302872368689364872785975840444000802518095138062596107983803117056) + +(my-assert + (/ -239344771695510351349291992975349015183687755312261264640655565 59880027487583466136533364102518649070390160795136023810470091681171428955831193 48344457085007359228086666145324485903333773379391455489556219681156342646858065 96824393663737121700189215323825147927318524415097221824671795011444303522438090 73240728471954064253765051525185557601431281145369716902120469411886093226662465 53476482728312567840603110355495270554470432250981685279567813448298175801364992 2468459436652089730331798017030410049989399340882712030505584719342958436741536069714790640546086933185494149096286590992747248311590137695839482679011866 -20583944357058654336975302336113341974001469085102805363209530168831840401111182124827636905521584509677325966689931599005216123375088335255672290604710305325984961984791919524676460851699284525672773368217606895110240237523696098521003978238685169880199868729577660354717875890521074505342309726366304528678619465048659607726264456481345739318939431629704180230985397408136331466856633265343276511285483458860216756106887559724757372775728879136089013590836231272961497930729470443491032308329051560641396901204040829291495325588896591482909336032903587307512310970849256645908744180630660878534263566681640143534823) + 15956318113034023423286132865023267678912517020817417642710371/3718709813392127924163278362562751486187605430152002432053108623099406465632705761508167478249438322470295467114170871555665890539409511492475240415534629792791729596612426725326976353265532166735941330128195885206087665506220364347120981130748862937276841801804372097254983242962029582754709606117339082763083905960784323141929645331591164015455383939302728076410053178677168172481507115685831178503426055335630689722163467637005123748113214310366231893390818795405612007113310547901224920768646006621130651182788173442625298859454337696280614462941186626306295514630883052819172301830539345633711941340491653447613466053205836875456839023743314390098829184111583809697328393569588632000669468187410368485286035179259523632217543401146996259011916302393091677624838641658623073752023082344005134299104409908004250830639232078441523519412192782367689826532215394196055149255026188549091956300108740792221660678858924234682223183500313556198187095251404633698868186071148295957994257417049500872570631774233307260384902571112475241073598945295745287525486108978093728296107260155093397986671349139935376427469718767763295900745932105722655724205000829205748307261900800) + +;; ==== R A T I O S ==== + +;; ---- Test von + --- + +(my-assert + (+ -6069217517368004039/4076344942716985944 -399587800008780737/578697755310708616) + -321318766345655960630110128852941297/147435729263904928853096856396980844) + +(my-assert + (+ -41285036778370718/305793940074617155 -1396094619926552183/15846027887642356854) + -1081121118676718273499338028514700537/4845619302294419132297197085940230370) + +(my-assert + (+ 15975644088444536091/18063939613598316583 17501188199168431305/2979264551795273683) + 363736076920798535449296038324193823968/53817254956563877935003279344562385189) + +(my-assert + (+ 10197734562406803221/17452826108659293487 14639450560606090654/236781760961536951) + 257914422508077920978698094723491089669/4132510899763835955061848877304138137) + +(my-assert + (+ -16810360766832230069/13652857552883800956 5011749175730438558/4169057419710079215) + -184295743992738197672588473692806043/6324394120121667288243293659228081060) + +(my-assert + (+ 2234573531734039025/1128831476977636536 5842177084459535064/10255356071975483971) + 29511180623959738330730559435115466579/11576568741659658592450950022331964456) + +(my-assert + (+ 2268894928233321367/45672733521488298991909987382109984899 -10510750087507287356/187832098427494353069556175466145198255) + -53883392376116199828369509984040539934420061636271022459/8578805378260910951788610598591490227836321974082207035230408675959411151245) + +(my-assert + (+ 14273433611429514043/7774518083776389556784045601066955324 17247074371340283485/225579726714102822702316919752160926694) + 1676942472465190408518249346164012571239098147062478293991/876886832336064155131767120243155911448808491410701588797601053820468509428) + +(my-assert + (+ -384768590020206817/26284423885474502132625533495652664626 -913687410374243983/254477371735734658619949996700223764026) + -10160887225658731404416073535892287983824191154410167550/557399258996959835387173465565070652935481894323496556880024318994528462023) + +(my-assert + (+ -4465222504572200650/89674568206322981678158378582739708537 4148550863841320780/74302497820894496090312266744880513261) + 2118016946376507498169590394563632549990739165791772590/350686547828419379316750498534703170285368675911953477374458878558215968903) + +(my-assert + (+ -4466938407638238142/281859125741189685767904931589784285893 7302241525893379697/204618108204962312932373858463395271264) + 1144186926000295881841982161759159994442430111060328362933/57673481089466829503954266461746705742702466399988738560842837126631263478752) + +(my-assert + (+ 6692616266348342275/280491911593106290120490189988812804382 5414100524539959087/183579771905991028181574615911067652873) + 2747240373316006570071525025488180559154305534334705425309/51492641151737853299832848099101317109893853469394209716061486746077629289486) + +(my-assert + (+ -2794289802081124319/15768464977850217600859580216291365931410230647587457388598921425875331529149 10869776169503285673/33805119742344157512165738805682358903614971418053290198565741206390317449856) + 76938383491719886409504555688515759257937029058461512747558964579607347503639994773101488934213/533054846729186819415263583890627325668798847177803707144003483502948153457972377767011992167761176556555806720273883868208938866192358148729990609852544) + +(my-assert + (+ -253222140119290489/2123024034843473393742534167007121513293496410591072104903085284304117612082 17957334013642389787/32058972871090153103034645121513493401113378486125580864856088310966601405847) + 30005809992231287609744177955201962181880644831204431411802631067134766877061419104162728517351/68061969937719269465960475690278941280799593161143759512261685488134507341176789799765185182008442410081522124548392827986923668912612728349293792643454) + +(my-assert + (+ -13318881947309618/3105936147298438543619802738126617974207009907186580731552500517452462642139 1850968757748704519/36469179946212878965111748233319050931475015876401494718861814560453153824935) + 5263262069792987469108717688485565287648879759118200779949761992573778798556738644541735401311/113270944257273905484832818286307416845956086746130199501242465128236430928807948126409718436237517505516279133169796919230385184900609912160483959935965) + +(my-assert + (+ -9937822914683494298/36414156259035675966580098631253549474580108307284844243190992829476777586283 -13712605099585970325/17758145954890657915358548152198427387923366136638180213650029984340849686198) + -675810254607579372158951115566887998278519717754376916387787672973408477396668549189167387350979/646647901672150721610792561233068038707362067627156669418022102308446036384411330678972562863413004325878365438890328206637571985169324874284800419222034) + +(my-assert + (+ 2479135971595944301/28169711053558469409458629766960029324030958129245230797895768033968717159836 3427244662960653095/28446538857424788738244844756675951434179713170118835630969510829753715142438) + 83533664807147783700314944003289704497366290621039272787320536148072960487262393639109696219129/400665390043739792096386856839000624247597803909916773326187593475005945995926511155915226239317839405221783416485999405286913042389632370302962776360084) + +(my-assert + (+ 14865500635281371370/56222262470894935247131881777606182311286871927285650835673424014252462156319 6436092572090050725/19282524131572095520593158313261757267758159099923763177708581262473988426947) + 648496060602737474174747620183913927791943082591316359990137585798909535115053578637078811588665/1084107132826611778585714784136700465449309125114745313342842325649687943726086785657821763235618936882528385000712567133180567926723616940173290425928093) + +(my-assert + (+ 340196811925805824067049620503247332111/14422464039094716975 51285507111580975533385007190438537498/3230944134273302873) + 1838820276033673324738967436225477772648372110186756083453/46598175588880723338390245118389369175) + +(my-assert + (+ -210449319160504160992731982827917332322/5436857856220342451 251628249079137248539965770847855056283/4323109210037952829) + 458271632943884346915405609513071881239303671882386130695/23504130271893362375786510953364243879) + +(my-assert + (+ -40984360445255688839942109197081457275/6593417935076565019 -138094174027187773198981391229349265879/7135512300754720691) + -1202957011856131413678873259651070808566709454882536663726/47047414779755620074837011989046108129) + +(my-assert + (+ -289704472880230079383856507128133962457/10452740760651010288 -55251460678415911958671096669490155237/10333740726609314202) + -1785630052601050832889834016432677758176770083879794496285/54007956451514283340719766211063255088) + +(my-assert + (+ 276702099951674677215621541062877777467/3899918017008359516 42623843937285717338660228144403811741/1973785812353331893) + 712380176058162142132059442064597996057720566915757732387/7697602851312240113570356856612843788) + +(my-assert + (+ -323480614013303716597188084301661616596/12957985934572321773 -72966206939397711493108854138997499334/4539020357040680881) + -2413780175334213399707013296172687953960842714316410700258/58816561943270580900205343368941122013) + +(my-assert + (+ 65443777543319569578713907336699651721/218804857459609839540825438673960136766 -61986861924091374470669233802827103921/65997977315012279293170493460332070399) + -9243869541956614722377007489838492339200370508580665293676272508698701352807/14440678019033825487758061900150103876633207457375858942267120523885980189634) + +(my-assert + (+ 75417845823236070411341994633288547531/70553457686181702397810927701121800017 -7132208259849175775323757110664708879/24379326462014713478002790304943339422) + 1335434330716260509518880689691257567128541829706203586134358870209350816139/1720045777955364955754847231620711706115121721983605654691934662747636370174) + +(my-assert + (+ -144692585186931942602350348772472248638/135233395864627580439431775527364081053 282512666765911374279543408363363928190/317835040256607665191397469890906044457) + -7783226336195038987381961251409043080655184208289882004756343793157154115496/42981911818671667582796085276418080952868666330715445603855323471628969373221) + +(my-assert + (+ 44888992584766727877549626240272070725/30583318432547259097085073976959329092 8004917623696885952432014881247978821/22005016116109025986417835664774768346) + 616299974987760892931461886440810919939264155149950328291076750435394215691/336493207496148335911511951044490614757807556827643881435283379298939260916) + +(my-assert + (+ 78378756441281199312006031491361997668/175125578595003447448566412156266355477 41128705932035853424044828385766740319/216359823601433445464965619660717081261) + 24160702340946845080381231961736762955784254747832931999121777482667650876511/37890139292913914697800186893609983979783140570423836226844401085057321416497) + +(my-assert + (+ -36669293296367265584135816683983780855/7341750629088488427994322429098120058 -110335983484012479290765295565662258281/5944410911181873015545360879141666465) + -1028036623331099574157832708037007047972965676333418398303213384036005227873/43642382546729990922161061763293407461832155878510163500678954788762454970) + +(my-assert + (+ 228535455883892721240720366651075744967/13353170075841095813026701300679754576855418298534901819672803635370738730013 50622643250826426975012800479360461693/18462345430382979738234695697296360785230118465695284267226773073149552698303) + 4895273294635392498665165879164922265508724130843670837390305811645771221742112327485665544066552056189958877583010/246530838530831602270074647792752210668736478466245992891169449973883874207653264921203783108295835419855394180777469634862446033810927048792871560267939) + +(my-assert + (+ 11355068601761731966774720678777239425/4604724775053993730579400400679579947095967462408565975449642189823843820753 140083339434585694465706029861026468774/44667214322013486680993684507177513903616004462434123967566781106229226297333) + 1152244506542792151980649054527153167035843960949499862764543674633978109831264344257976000890169981044543787620347/205680228421222079539939271800361418862113882206694593495620042859527547538342323521609420336002641308832164587573546802806916292021672743366881933951749) + +(my-assert + (+ -1347509007210283053816302848714698886/1127513773036247565111791991337919355855664936242166138889250311777351432819 -29464928273311615445392112247506626497/61933028109313748081628643142485450090725737246358993405254280723087421657760) + -116677425670791909053501267317366054796703074907755330120413752187834449333299886015456661052906469074533366060403/69830342199092322009251417145364324484174202256910311362396720371574344280505889954115533896831727771442604285956749924105078563356474162416148250025440) + +(my-assert + (+ -324250487660721070279458563122233299722/81069650926979269606211148691445887485067008319429991878657612702576019034861 221744296343315457943731256980089803078/69422237643162665956763790134527973903052044485041686255401689654420090859107) + -1511153903564243978242173323335554031611949546418082039382510246845821774680210236992700372319944685567533765722032/1876012190766999122356500320654631447623282613780323887424324139799202291067983209550065997185860196433399782230215269625922714982832188312141580824109709) + +(my-assert + (+ -5518324152042099343909980322067306333/114786626838714403445081775763480415805466836213320421844559660900880511042496 -34415425451618992284220085078832944671/96012285963709194218263616278916829663708037691620330613749177799086889040577) + -121088040955051148243092870850103339772063863319219725752028251933576579890093496821887384992074112246777968211161/297862876779681729593084954525306275464788137269287692384941959703420459939692410434239827100068259769782676124741025632728203586961467995819025176090816) + +(my-assert + (+ -14763921690861243371082340598041267817/5580497386043551028888310256097864185640794395615400088682607872958152738111 -37917865546640067592937379176813765341/6460563866107795917092814416816176677900242086501650458839130903088333290440) + -306983808565398982164654624310995401934900925070311336095043743767915008644459192438083753301097540174379867380331/36053159767181973313125557585868206969047484351694148822117591172786449966899079869470557965303954072842600790897257698854023751399649072014440219958840) + +(my-assert + (+ -50167218239107621378232529938205077788547946059832391744348095230748591585676/15685777859540025727 2959973815535345735348053015389999235839609978295604181643547897863515739931/7556072538495923601) + -332637648328710384664787658442281566361265475773778265650094684540358159241317316408573560734439/118522875329417757148187346888166482927) + +(my-assert + (+ 36275100136090483878026478935942224245036692059657264537598788566553406654319/7192442039871568876 31833552596558882106090352174644817045294359487590746360517241517440556146007/5115621724114081523) + 6795584791386081942310910570767193224876510928834120433155946649367201608618436115134135392229/603177258173744207443043238127434068) + +(my-assert + (+ 1518304705177739493483387141342904186483658277690975456045607777812450680478/1837349761252804045 -98159070764971437450169149833809835519268242923913777966502463698396945141091/17238232824535200528) + -154179655228376218743158291724235398278770272999447263973992852061897564252670941977524115620711/31672662964580000612902147746364535760) + +(my-assert + (+ -16820231344048323866426670709751443650129113909724546927974450301780935205864/4879137683452153951 41987219452495799378686134495924115238909423831017150785452046648616005475639/10470103987572807938) + 28751853386830083847297108941057082854166610198448421498169760256533906032780671559334244751257/51085078915429149801779227663330863038) + +(my-assert + (+ 106981694162678522688926793970551228214793665448093395251834862896418045995969/12359470989873920972 57736849967187961211538031441400807467468650239660040144967046985609433512403/9148121311784151716) + 211534804819567028232303054650327703050869189253958355919997046592895748577556985792570078031065/14133242495605447754080611005730273494) + +(my-assert + (+ 32477400086615533920132766925666506741908300936974348739732763951610256880146/9045135183308696243 -27444990730472195954051975667481893116650518055101159075033425831129583042846/14815776448343565085) + 232934248044934592851252865496377968609159820017147884670610366058217203617961573611006127074832/134010700820948737148715427669965475655) + +(my-assert + (+ -110053921687226074580746319073262192216481755737797790655164396095655530752161/255625377233605953547425802301922658850 104095037267817888539158192425982072195078148060302393917025130946535913363779/52156238014583575190277280296975732513) + 20869334635774913818120011435677143948904421430726712952150525645851498022294865158343391008006649321440592131083557/13332458017563665620865770931104425383051282278510599570476131200251352190050) + +(my-assert + (+ -29732769078100192507326444863945498799317005912797369958801703828462203585495/153426302667449722633466432797809987061 36094569840376017510791155197897623093337784636438580042046806320700826250193/73286165979315961333009750429763545174) + 3358855747298609357265422062476767573626163217619249414656940907348235709105513077913806378841119674678021275101643/11244025482879487592663298816607141776071841230792806495601092332558428993614) + +(my-assert + (+ -5942892427460131788264792587455286675871284855854073854440582948253436001319/42136930106315714728428443448730580823 4013357443728612356640061171485791666303136232331145404661874650095235381569/4039594279673425548586623641599574814) + 48367895947790658831309709091377784501687363167039737892874371817395083020674648576881857510385191335175551957207/56738700606823969419119152217721454504573192499839513549171731025354063974) + +(my-assert + (+ 83833896550100013648317056712064289497247852876055488793078639582729685477353/188580876675619574786621140720273228537 -94310653397371924313725082402708514144086936359594289802762093989853507835016/223423274286761439988276492107364036191) + 945257965914081840217765265999453398105151083284254483307155736205796420255026737575918161700355729594975143830831/42133356934734885127066999419230498520039134905254787577957770920054881982567) + +(my-assert + (+ -14753992026457621496269953958381833108089826525439816493815533773338622353285/187171041855711408638339193132645929319 41340837577662628944845446369855468662228665858415210386857356535970453143469/322471558852595372991189266479896691326) + 993354944176102401496932276511264091214577507066786487301109889019709943488537161608732610457423116833164991120567/20119112546425211128699888199278894685207186285215928241217590790016852128998) + +(my-assert + (+ 1370528773439579327226257222995383030603284075640526658282329726447335048230/305600505683287165495713194488435114383 65450762047588146235054351616480175308174618406941901794570541085963681607527/78934496562987400429145916504112602768) + 2234440886428442112499564751364146150136438855986167755259621093816030535881959724370423862435538502079424185584609/2680269118389404699570998335430047660909241475691839354273569734988880268016) + +(my-assert + (+ -76890617375308981455205142622328108690129081798840077873315966300000409208129/15716637731576156581128288257209679492686622162926707938907282962815471734862 38716252217351070567267262306332875768795464072349655597599997486613800623507/8966639693620677733207403249675415446338239705879120765911896990394928596139) + -80961151400006413290662155450270992168701818633203071886556882897757813544592915596861717853520674107309124394292702460320442121704840951425284048212897/140925427734207212133604717335369986754855062343668899363006574618520848268718851310007161609443093589067206438198588881828988648068282656538084484897818) + +(my-assert + (+ -43290760758277846058307167265569849910514905939554272559141355223092464986939/39390771697068809730875092892395235497943839933482798653607450783947201796777 -34021960935937170163894986285771504067448629886312440795733904794894095253649/106500928228745564800818258673435811176493306775154643113582742982704678574998) + -5950657500399238361998292872481533631424138885403498309639150240712482075115081624153513501886127772738596607451116548616099047843190357858736503567640395/4195153749384427435979718872073512266029328962522899010907363614544821318917440413166534226890289043064894115954085809567292470182917919104836361549181446) + +(my-assert + (+ 17906146982204022925114071077515882010955693727109005464426577098738402001871/11978213712662686419384559301746021856683603106261241838035626618416021524231 37108371752538653389309509075248119316034595087990649061240232817571629131708/23044877611981158676785639370406786635050056158699399001947422631523989139615) + 857136973087880657664203854652754375000000796400911171478039451763440064550649429609696307332611304395324153178602635490321877797571177424460384122636213/276036469018466057777760709173569478463866562650149880633721199971933767458324034017734890892482223472007882939609440193626728031771767304374122564511065) + +(my-assert + (+ -77062185592993847534024832256462395143306675613123510837298699277378172890089/108133793614758275822883834459865239455798743725021300772336023406871185253111 11169356025540464491224577661206910726665825152149521753528516637690366838655/6369000033300801574913390611244042297918207179453133439308688067382050608197) + 716975776667538986425481530620118513423964367153518065425241139444161780269039780459555836804116752462325735011822817367819625929553250251515977390346172/688704135133337463423649074673019029541747166391680122270752018123634233590688096940261480888455237095078029621363428114402137147558304641222314936350867) + +(my-assert + (+ 13583698920327742567560325715281067532806062839142769830536738488850089822247/37364394142255392010559408553278838878570049727027927213977555360874308098434 89809462356450792524214360688853318641058652796345720882094866396911421360072/67457610947238032712889230619376608100793287037427539672885124981055281513463) + 4272000026182362299819817378001862956001381379478285995446709640464951377212652125169846305230835604666564953883168949950485767679005929254184987140738609/2520512763327523955464432226120154092742373168521113224665257966793820057379494860454732800329019773731110452438496395974166220481124541266348389100216942) + +(my-assert + (+ -56124163112538495128545947597589743957824668875494126834084658670528264380488/4752969512023182700122983723156599300062332404522277372984645779569746369511 -24794747728228571193100294011820993825205231022194400752319729320185378063197/98168688073468429337427023004226732413974455700654808087001957859427678524065) + -5627484141989830997868845457242226973925524393512774885292323552602180052845805156311097870316601631410500655735815037997645271136502511615781690896430387/466592781448509275992390948177487068548424631274164031114910250651063315574511979617153568070687706304645818907382693929886654490427484894987856595782215) + +;; ---- Test von - --- + +(my-assert + (- 8229768172162771789/4094631553683915058 14916542302144281688/9648520391570031013) + 18327341244785642013243791303754634353/39507136041685332578233153660317693754) + +(my-assert + (- 13554976081719376860/5850035209629724601 -6813034992928443315/16012083383654426278) + 256899901877002811987490932642058619395/93671251573905451634945335611797465078) + +(my-assert + (- -221798849980968127/896588178875000428 -10118632981534633697/16809799818197706916) + 333990778095757160537366868413422249/941966737890699707694484674257410003) + +(my-assert + (- -10398409463665680242/10672871071680021919 908300169382593227/1663860017749090135) + -2076589873614048366639515256135965791/1366012573135328609279238070700513005) + +(my-assert + (- -2198518713248421187/494031967775171833 162489257999262168/3608560229859558061) + -8013762081101965644053022173225152351/1782744111192743850497670941715295813) + +(my-assert + (- 4025149216228566945/640594137312937394 5467380276809034025/15813352732084653151) + 60148732603712157399679443099667862845/10129941051434949990590527231467828494) + +(my-assert + (- 45649282670476595/278386580761220266717341154184065537 -8637266763647548631/320617180101036447149595031898805939080) + 17040443444897688379155017841073877168061229451634462447/89255520501631886327999278515127058459530587144975987720686743155549485960) + +(my-assert + (- 5648415331928005377/86815630814151297970860026950116430492 -3858618729527320883/27855468652821710859204555976171379400) + 123081918822962876101148539477322308270739795776139149559/604572520679633516300271119677141637780408278090307422820905500994965166200) + +(my-assert + (- 9781572955588417059/112881800445343004034168709823458687843 -5059688483724168531/4577416283528891230944530353546966748) + 615921077060787960354561606126348783111829996215681822765/516706991472571912574910836774186280180852506048696459094758451180832844564) + +(my-assert + (- -4967914039344839478/238170260180199675500515253723794945205 1851848905279976507/5731170327270969184071911155742503278) + -469527297115675955424190428047537920421409443442551107819/1364994327983166854234805393053180119374354994464588574791772715189542881990) + +(my-assert + (- -16853061581795824324/96404437352723357070647888504166371117 2887610208906060444/32980643277330946266739822018299212963) + -834203249643667606680245846951263316484378801689149307960/3179480358681967952651970543397987660141008737601948320258541111852875189671) + +(my-assert + (- -10766003534404571638/1736320411127247334175538439020437437 -220564366893542891/24024005562370344889629855466198025799) + -11228676451427374102904112111967705085778332338188090365/1813624835433832784217556253227924899981441517333394378436857197512671181) + +(my-assert + (- -4039872531792560303/2717817538621352660433068255065439787147153801016478776178010367557953211548 -17969900169229544519/10371230759745501411127733226376204123221866394120596070959771442399588297129) + 6940459580028931824293913174633904994365279610168782399332846513086074139209123514834476635325/28187112855925579976299840753672542065528422968220885043792832460046226866036339425358907691441054924266606457279617295071355282523744922239122018045692) + +(my-assert + (- 11905720953886477738/26349991043344773150817457299711471013733618033386232710348739943906972457535 -1868508269239354100/7915113871665192715310471309271830385175189228544536787145345883401181858893) + 15941145914794937177093386304443205602552827651536706608400845076162777444155363739893353329726/23173686625047977587990304423741788120258508897732978034793987736019678129860415537604628640859289817332994555163435451240013483415438259775849311623195) + +(my-assert + (- -2449440712560236858/3924161613720467738425590715321110829708355586356453490516463081317902575263 3313932993860824279/18392642760231276916239249302906853654153090246504347205856270072174622214792) + -19352032211145724571420568734409847660231095572377236173431089875006133635431666731719362137971/24058567564857748536604240288023690440577404826273237225585673569644473540232022448230431237781096357243673961302816983638647478040822458289501843963432) + +(my-assert + (- 2375854596996813469/17171542567603713573317138241061150416263899780234956304631913156611236192733 -1690236091628058998/115698505401619203741389026136939663329574241316722960060260525901879106902321) + 303906786920788985464713527121698374469813384178920405503303785899916213843318155692692663023083/1986721810512032345893371071989737461519340072368099757524397292434629497187713075053126253107235936414498803590298681018206068059043963268488989361033293) + +(my-assert + (- -9066703779833220052/53996509329904595759286231403247566365148374715934463324003880626270687736687 10104829441267883881/34350188217372122913844475743718288066233853695548819225257606841719829170673) + -857068498550946301314281599902676812596945461499639532351672507051201056365247232693696093577243/1854790258563312749374056592838765632813507083399863975139987272744324437901043103651094837595789610803765303659351781344942305171362498886075754606580351) + +(my-assert + (- -712905705954993103/38361275706852471555340413672243335795384295466685977818182375699688812583403 -3487523845474404757/24004509207225606167828624323100421869226668573968691661898194620137716910067) + 116672912187985693533424614379662678476187446315443107971581372764612623068602629062267386180170/920843595906060126846114857872490000269306626188013726759480780006531676144330596572087176480154495471428384288229491172449159350622326294294528887818001) + +(my-assert + (- -104068455909264700529593875361271227125/3443783531459345396 94266182755532992545775726171008609186/10986871169556601787) + -1468019045636814162670978305715811638938423723806410280031/37836405995984502494576730289263822652) + +(my-assert + (- 6250188382163250356218308848100308290/74975517450841979 10057222263694104272437942231238950849/1377150882331486572) + 7853407001895533030925726629648778749078643531548391709/103252600010686800286181264132405988) + +(my-assert + (- -325869560300902552275820653500571757882/6390430580148850471 94468553562411191993094256419298214695/11908765973274803007) + -4484399064985071999330976874105690617426359030318059422519/76102142247451389303559481900024166297) + +(my-assert + (- -93570528036598407567281714804477572547/1681213810574384291 -244906502561054838674546679498356325029/6878656438675875801) + -231899320744132980638168050942881155823492361410591515708/11564492202898292712047439710761442091) + +(my-assert + (- -81411835730261219386583131450337332863/716127167248934 305772198898084305417824619321954306670/5852119619187572757) + -476650772889757879179369019399921041943854248979406203071/4190861845290706865359628655691038) + +(my-assert + (- 8378821874364768218652992773582270365/264620166167099506 -235085292482743132422942426826553295351/5218853722286899445) + 105936154887632142427944491040385766054707164161382644031/1381013939193345109641609957531174170) + +(my-assert + (- -46932041053326337601984043288899377207/83004348019257810472659105973646518650 -172752976692389001100875729845538600392/64697064048458368935602368307247306331) + 11302882932785858045495103305619355060523322049764297548269071809310077113283/5370137620102451116225827082734739449691101289924623877117727128768254573150) + +(my-assert + (- -5215113722152182902641295804790889582/37267147737183802417372262122851319461 -174324915479281952095382231256728338942/198797486533978895289571841018885549001) + 1819946959828587625889363843813156766676787993042778284071188313098762447560/2469538433480866339929667414220581052912334718874062150193407525506073469487) + +(my-assert + (- -308468863588547635528373349890793262605/277175417813474671446046438490775760091 -88071245580784145343997181342216325733/109042592277517238289414020635536175644) + -9225060231388102579469362745283215538990500777711808852192407359260779270917/30223926073985207174135233898799350451872811382182855106546181559011381423604) + +(my-assert + (- -139281160373255540085888405052544101003/21590054032847718908692432707921390245 -175128181843395150044469443628898278945/101874815793501611839718166887463701141) + -10408215647857282226079103083273257459322595128147732742048301223816698452898/2199482777568107961766315941206227462112836158088743951492692685709912769545) + +(my-assert + (- -13653637423911886957204229566898836211/6724361745919744069899921221745423919 60537422461958273742622747790343370991/323722395245687564470126807800714703749) + -4827063738484690108652046326448960810791170812913084889649499536314520788768/2176826490887613088066161490358401961235974091796973399049221882998503572331) + +(my-assert + (- 207284509647982883454717074874778610186/315575836476247924963087075944676754095 59454580888278446469281150437143941047/3799382139920332759258392540934029749) + -17974876032324524053425850245755672169670471578477359535347261991433397414151/1198993196898275844180025803639723883733761367273976879884312817813487572155) + +(my-assert + (- -149255714031984711085009662216310611563/61209488724728410476016289765233999883959861482512968048939594260689484910535 -206353007879160639705730135450663155/12341134377195982958424940281067948493740598784362073339140017508008773524522) + -1829354061323966095884091779117676852909282652562065419187935424186237303685407507859167669375269438805585201409961/755394525511335693198081866608161950899365908489933659716533239785460293292606918153507868614180865950008697266433342863460741791684603303270127798639270) + +(my-assert + (- 286228990947356503137685907205210886138/64525193112922470913382853022276019736227442678252533126077234112153953877503 -93778927468512815169462456699065596479/70019706577332037325570327903202382111804035215024271930215402736305222068556) + 26092773364888269343302672267572690894453186378630697330693315371426642609003667116358459590920104883240139740188665/4518035088612517412858008269349176355736855744033363257986123715832709510554983209440815107866748014413528943649032845277041680450752670951433682692095668) + +(my-assert + (- 128067958966292694713545212085241612749/50804897676960765097908813878456128842417954009101908722816951877006748778869 -331437715897535092432788513322484606485/102911257177761006574263802557003927106564530572416215828322919550454967864323) + 30018293903870953799879886574342637699455128356488843398998059810000258259055116602688738404467489640369684487419392/5228395890723542025866546462435908982096651119675992137235094920338650164475761939608730060759309002063498665792819192135030537577109853650729817121390687) + +(my-assert + (- 27065789167947870065829490227927612633/10795458608984562931374526676297845621730864739104955678079256994070639461197 53314096352440087811254806167289750292/44807028208492548064750449353871285104149154384082409595945081934090139448067) + 637187458285170434834128234123875152637450428605039275620795715002449318075555518355578432548587274399560043210887/483712418416385035748598509413117409273155809870339120248356475239836262578288026980177669113025449532258001487616187498682131415946755647640047843156199) + +(my-assert + (- 275528434092876314751862670579225752027/23290954563951481764306221308726902093226107549717031306984541394996363441752 118398743375843543978994815511147957868/26050691402435592629863948804505350954161759382372519491414484055670238339031) + 4420086456754111377514058698455330162869575963826459083894390154200727636413353382047981846196341965799691593361101/606745469813648893293125236863835131523556569847025597910312571817347251611730291043895952533706547565767925058454286630395458711598751591845070996622312) + +(my-assert + (- -263828172858355421790882308711676546531/27836884730007976814146538035133148053942251062564400015534567388490010158584 31580638196736633522674344981675107601/26210154715367115936541726366619494863883445533448748701891278370021519416412) + -1948520953518189888695889830515156795224640917019574042614412953331052369986548949517168001067643449389746489215939/182402263891837359872743630675214135004512597266032306942151126033873543370078488920825920736994254287019873146147276876145783659805845233146169813070152) + +(my-assert + (- 43029409555492054023102681165249027816896930295612442385573977041111849786681/17478431621804970398 -63831159286570708329826084149841946467426290005331979697932225104261019322894/15909114936773208135) + 1800228375210677909820927489860838061135888931548234366640994061734196466170531105718785437541747/278066377585826623354880511023167787730) + +(my-assert + (- -34677827126365037739221949705076349308552841821108642369491195428278121711851/12321935233094032355 2466652720703038662112375481129216761044838204088317060529010755963314905661/458077759838279587) + -46279076433142446690218423399092373290016631287423134630356063713373023144989129659854095947192/5644404488448083755690706619714037385) + +(my-assert + (- 75657421640076548917316021979547903196453821552146142751737530624725671569062/5416811919979369403 -51031635143911513328361770575139950616395278082588474953679149885798666896870/16274277637120569843) + 1507698654622877634185545368063085304919907004898369478770589865697455127479301592176158803465876/88154701093808389139357381843158713729) + +(my-assert + (- -86696779369804422745383183615836359604633179506005810847902134850836986706763/15354752711854066426 83875579121692496325618937810567731584819474189441279434601944065565889174333/1890321146489013312) + -725886765676185953186290796464189476910148783977596698524963064505627422317719186476684911836457/14512706875163632554860591439823131456) + +(my-assert + (- -2824584270835350806110810310308644313069326027498380007733023821989145840779/3128200028313826545 -16485532380752962986834975164722153533427821569516340079793116204530103476885/4044901389917631001) + 40144878017198534388242075435853869853984060096218401720566307902396394251666454424383286522546/12653260642466969643085415999628721545) + +(my-assert + (- -71140717297594692514165816539390347954764512441693085945645019026357644035048/15130773661553937219 106518314860779634188990156539381479314908411240039365434170935270962911954978/11202282371121185733) + -267626990691150539404999353980899804835901788880218020004516046839225745741587662342920970677374/18833244338916713919008552672213388503) + +(my-assert + (- -31372444086039981530710911528326367048894875160807395940269724829549418985367/149682691887362386596593782520991059630 13980025800771566396092717430902170466939197897483207383178768135899198010674/143215924045734814208985239450703841431) + -6585601463869631351127457963734548845246885851328680299125624347680443020577881573937479731612385878788264587830797/21436945032301618223045694723696447349670080755369221855700055538448185530530) + +(my-assert + (- 60002561005149795132492915799111287923312170708430066011808292212167201814322/16346766380600148228286881361520329811 104734497917913613491539581495799848702023341599268915776996571583385896191203/61937476024742321910315674059586179787) + 19844918952732846654680216616282727016967753441473733514766184661191061075852141231786969917096326062063227788681/10024529215648371311559365663430434349900555024451481776473735938354274557) + +(my-assert + (- 78980655687309201443760271907411093305339297143458162112992101000746746121121/24094471248783344167514231679460830840 10562090177736342378322146805187203837437609238688017154037816697523731420573/74961473522415640988394298626742882726) + 2833009175986364875175323375606672657538996734036576482627590142336455915129629838687125527863027857335645122892263/903078534276138789186206765245648729133926893901427360507431923032322034920) + +(my-assert + (- 96507496069338193466683209170737942070468924698476218759487496209308948365/19252547784216386872197161331387216893 12563973560096321588715986952435909079270363887929001032891628645353358046011/79879611474172059435223762585596250921) + -234179520035021783886726161079163865833895106001667476480293126893061678147610754451356994012799045797572757769658/1537886036891137155393554113191390737924110193971845147480358562685078008453) + +(my-assert + (- -95307376781556674397571761484869767912211504027346871580288574968524683908606/128329921725822403056205582017133271311 36170894925879686192917617159219095595164782822289198001474013555499918728596/240886887357120796976726436320063138705) + -27600105449672599524131749634403660999916186956076872373762346977331203119722064380924286397976905109959929163304586/30912995399316310109755266138690547023211992922143297688759057498082990192255) + +(my-assert + (- -22104893896795356297688360407985617971036912713007110938688208155601366216839/5790727918973991999188987227357894380 -2339372311396919406471876113751500811577555408710269902369834593304924842262/12937689744925498650506694361349920911) + -90813196841584888136609582546105640167792279132393576014002859436259486025871518847027719826829986116492656710923/24972880404321196721702428178050372850585634300866259560981343234830460060) + +(my-assert + (- -3426218098660813853559652497557253942819662042768623922183022792185928242671/2077407536662385613357832628600529321326686191757127715026249042748302985178 102639297566540827510784861997871251414598617775200449087621943894148321803293/83089038429507982364103335021257902316010144851865721965726693103637274338545) + -497904817589969304680335736144278473886197067420059149312627956679073246109792679236301202959163792633927112737045328517845259242265445360227131779644849/172609794647490471018785535271654901168315737813115654161745630290269473799997219289162551586864155467201760250711449118429648095083028041134558889086010) + +(my-assert + (- 1543899448831604569141696144740105016328586790221799945430718394112623114412/1094690716976737526626281319975432667416762320123576900412499904933271786567 -101835025746074730017715423582062511397387458863000475669454309217160145993/55116548932808468782187525862059393507883043749327746382569396580129398962) + 196572266866178229534134252625134989714563665559807019513454337864363053729628560611312158082929567528955985669620113192156991984486011150099776316375/60335574468539540262844259780498204139853746803235564167348945699931512713417761400790104247218084745081610815218855896912895393599203789305655343454) + +(my-assert + (- -37581128364300495505521143552535972339959603365602244668159915869829949338997/42947503543372015019662104425995959382231280059683481488692141811517675950053 -64888994735350842409379226446854438865448614840503930577860382883594178287934/83188698741706753136718468601650233481619465918167616089202536622553688681087) + -339504834548876267781536981106771553482515399809961247195394672491113984585270709765073243997043174508213253440272888923497173265137136111635177948889237/3572746933977957867604303713153220827104741303667912510494658617478381525690274918494624922428110123336345510454960178899375325287131764283538305257747611) + +(my-assert + (- -16230533405187239318665866908175768720879595131719076634847964191318368133798/22572606803697929681675696479626869642065470042484269772607381297011844085929 -3238806615045730440879378702226410558103197865253164974472379309242480970831/7167633180423354812410246140643720752789573307606828791458541239290047771821) + -43226201536346598702395278529841763047400215735214225929426206339139243925579733185594282160061132691154727543083543034702325848468839969037250195569159/161792165494835249202675342837643048016103040739685489755239980324180308179745586573032524649518850731442178659412287492012066453331740508600962908806709) + +(my-assert + (- -58154703770626762920775801228739843350302933064569814497417973139312614069763/25655935043535628671780902110427599603857741303802203417196105196580175051005 2291927744682353823611191393035210406213286149316388597509251757479544491322/2075117977066796442381930295725401140983312287419314083032058820231519915051) + -2848879691864593463404526996418656511058536739346277043463623510210968076493148319480555434626780964688210750895957968447300033820091387019574369485421/845064952814266442598400897276554701819815257830830535600041451476645443978805142044657833921127247033533628716506571358424324423237490438402971304385) + +(my-assert + (- 16233726784138742204308718138203086218138595789383817317246449554340898453104/16370584482945481446847872945862788646563748664837147378940234530469832625057 14431071141710676049963542765626402177344958369162454874051268130438178883381/21166786163219212747261378458659387864767326410261049063051557406799162784072) + 107370754167217929909136144689909613387440429633745577224054233373886366171618903318258855919060113440621302505589923655976636732694637334616990468681771/346512661117421566971293748815177161526095870176610277140325665174756629068111228154091043637596506814557119477231243643171068111260010676990408227692104) + +;; ---- Test von * --- + +(my-assert + (* -6520062188352981842/3213004995534018829 -3812444292971845716/15284944374811818089) + 24857373879807849010516976362973488872/49110602632729971801355498746248797781) + +(my-assert + (* -844583948128454879/4750740551331102615 -1309778567130405125/4885884698278749707) + 221243590680205607733892613510570975/4642314113048197066962569716783636761) + +(my-assert + (* -4579815856418431271/16947444571374397297 7990245706938186906/12540719430158043191) + -36593853985314806270746820601513137526/212533147427761354206383017714519654727) + +(my-assert + (* -3587966953201943536/3194797554208122281 975954052071387816/2707062718507963111) + -3501690886675668292903668827990357376/8648517352177231144330968693325176191) + +(my-assert + (* 710265334225408429/567023629756400552 -5578988760400430103/4131535930210536898) + -3962562316545608552741467762441538187/2342678499616965424161446427863567696) + +(my-assert + (* 18305319006789031727/4480148641441744463 -1641093267260986094/16028097657311023719) + -30040735777106040963634910981471804338/71808259944297590021537032075729917897) + +(my-assert + (* 522499067029593907/142530390958606446621834761330018829110 1567459634764499377/31663510497342378306792964160850079086) + 818996196770998943862055820464495939/4513012530308148429025282037949729145117603192483641232823845248212618993460) + +(my-assert + (* 6214041481074460220/139497414619784295310756757536261769729 12187470171919324678/129216394212432939561557938117593031955) + 15146689039532873328968703771155061832/3605070583825050709361064709099418651298807367637359842488375232197429738039) + +(my-assert + (* 10022419596195177499/91129297586760817507648681092594591108 239769653037576215/24086455608554015268646156321002022494) + 104481394312031409685890479072416795/95433990476618390508514520731482064738017476445225501421324446942302103624) + +(my-assert + (* 127731839927226607/59760640855511386051149338950192132591 3679984267166095161/269870724770589242613062477043917992045) + 470051161348371979221331000573148727/16127647460431744118786930146746069875784110572380855085272434637353123238595) + +(my-assert + (* 4919926511230586366/29288587285987487013553554568227355149 -2914615432991234299/34407808954885309804037535414452526052) + -7169846869407694119621783007930483717/503878057947370143933800273784055481319429768630967123178484618174989420874) + +(my-assert + (* -4322680734125283661/246950524730861178141734701180345535020 11581515233057355754/82204027418720951285150957025638971309) + -3575942340708251875937466941988609671/1450023407574517046920597087724458064116343346221474061477327267648859624370) + +(my-assert + (* -5552456004563371781/36434418778024040927761226774271610950778609263056622471030041615086459120568 233319937833204741/228703279535756717601739981368829304509550463672786894384479957768850829340) + -1295498689806330283646616799874813721/8332671062513255913250553083541810221054209355142441164334390514659539371361850837178162594438925276666798780352514152276296209564179606228713851865120) + +(my-assert + (* 7279569964232187047/36316165899095632459738478614507512808578186173163489609755035948221062420580 4568992288187244990/18279847281938710983382796940666233712517527808023718591530848159479207220137) + 1108676634263212048809114991909788151/22128465550033953372731954247755694375180631486898426116907313824243654714198100644737500721615620412852035450119116976232805701601749863504629937973982) + +(my-assert + (* -8689289043809733973/34365105035540924847908154205433563929060132734873649554594240958996510665976 281724695877043289/3383396067954681850718083474385093262190311835985400909911383280975222535225) + -2447987313255021583629117408894957197/116270761252098802423406562021935246701911690887646043563899994409915142686943691634418411056232663942535537938126289647041118885713303684881867869004600) + +(my-assert + (* -4176416206981759902/47077361360975682486641492558477246171356187409295624938308162261216397376441 -10870319933050648575/51626085927005484523186190379579228801774286705829757742503501130303410401261) + 2670528255498212232918897515060496450/142965876637554026205455979922464979254073063785755559223760631646970673683621524411341782655829702451013418009338618833412062193643308417898164204593653) + +(my-assert + (* 4496049401725150702/8024116634872885909638996643719901973664008349644172107626390134736213108465 -5231341280619167012/99267989241776204190444307671763754306088564051099822830201760217121508089279) + -23520368834947889555464127765407042424/796537923785319116837266627763277272873506235001122453584405648384893204423914484193595265931840447141766909166026026228531619859740155558402735330646735) + +(my-assert + (* -2488955833769033882/80573015130339486598712021266263458487997757617589137912729682647628329090307 17723590657579960683/79078600039601362101827108583564759878924923849842119643649415446502020994810) + -22056617181258995266120581914227430703/3185800618738432636378738398589185111057563002909241393794402306079667392482341108052833514927720630087013771419748846412352850012097731569487991234153335) + +(my-assert + (* 24410613567363183821142175154197794689/2233491913446620869 -289777146895293391500645889398422195537/12394177861163531771) + -7073637953514043162500219088395995153310329907185649946877180402954938102993/27682296026727883467940485833673128999) + +(my-assert + (* 15029397898618080393623393093137341347/9939158597399833599 268484092305118852707129202725716126526/9752180454987984749) + 1345051417567645337656755504737828287428006597367109244226136136424901090174/32309489404196149853047846865649927217) + +(my-assert + (* 175291724581304230067306380062677652261/4791591464449055089 -207911166974886786162808240992513636954/957635297799905137) + -36445107018739410292029741836217649994267718828374576884161821761303211252994/4588597118993154438342028473487092193) + +(my-assert + (* 208446980882041538439350888438428103817/11756453246592156788 -99855903858077543170703702663212319708/7775813092266901197) + -1734555140205305628415286772698507060801514301420325900368570916304368260453/7617998589456250715053087609460739603) + +(my-assert + (* -49595797981179247160347259926801311825/16426101929443877636 104499598328969971414586784725010079457/3085074725343747115) + -1036548193567594227670217621556353400490405002875929378150074378019016735805/10135150379689493069951723318357604028) + +(my-assert + (* -288919818051255959565698296502103975540/9373352185361138021 77343596824463059344208562767410464067/8355013728778983070) + -319229970313622361785032672064391711775428287673147624981393545586243098874/1118778374191039878067165437747032921) + +(my-assert + (* 301194765217764762175383920433701358543/150076401641721289621709469985978858175 -109319143590504335906407585568245068241/158084148208214805386290412276525928977) + -32926353787549066990014316879429253235742017240010356390402491456481443332863/23724700119685440084214937112355810539035473428177368317381421021523605836975) + +(my-assert + (* 14575317438235510996984657523859363247/6747043355688580686998987940004831062 -98472042392613093668204392119412188287/152397803267436514292317070561082866275) + -1435261276663720115408306632770383012566806521695455296458086302958691687889/1028234585957093005711368462502470683211464374115746651290896689614112234050) + +(my-assert + (* 7543367187310376010646193530301789591/61115754966424662873097894247178344192 309940239796651595482411737112678240799/200261667764086238794802895148430893795) + 2337993034909171213000031444662193658341848356694420878002930517675329723209/12239143016237439360279809707749702660797878084581096344749106125186707088640) + +(my-assert + (* 306232835922656327867425959604977465100/55646521674811091128956181530575055283 45245255551837746690160535427248646677/3669533234425940180962041078287629087) + 13855582919684583969821610044729507626133731299765443289084519977056998472700/204196760665922729081584465192637337445710456706084552841012480810023816621) + +(my-assert + (* -280037880297253633994139513185953058494/23798550327416056573646642830182072429 13967268482262630670960486883264178489/7947215947745048068401387767511847243) + -434596028812829556627014314125713048434599389957141408329542154357763726174/21014690966139335562014814134594464675233042588696546668504776333756662583) + +(my-assert + (* 87160410649223805266866345018804635271/204719779683096591635231158476535039583 91197762560765392928084914476898132964/277206223024759381433146631560580134513) + 7948834435086720002947247338196997812861466884983039250681993725808882173244/56749596904412078223459353928850191672356004665473536520452927516595919428079) + +(my-assert + (* 272801380449749740391855824723351316848/2170368723435176720708253536680067463416474841046765138040214254204061862261 14545537787709209389572055399030228996/8381323291479119825335849511027103148981778425333781230074116361235206363821) + 3968042787871071204066360146704950989545352280096012736206796950415592924608/18190561932825050861659739926693806725838682397154479213760300500132465705680046683155463862909993066621811136554677896021527098482779305371951555659281) + +(my-assert + (* 58980225701104541897366713189611773567/10973700523953435846969235385386214078292603476932194022615006557054104506344 21633357583056027790037764923811848217/41236459355840549300942497778444413350482341379076368704834339005347182486274) + 1275940312921345964633100864283753667394719832288287163056787891633576680039/452516555639171997520308257003811683819837367444947027711901120987864272999978391252372420644671039873982401560595091423172287702745925783369137325922256) + +(my-assert + (* -39569537110370574225194522625562874655/36290593978404925051095380486087641410218299612051669925683823165483928853304 39273660356839128453616088747231247259/28875229647500294680887983884278577441525691250738380954940513956990510132534) + -1554040560950035541902707236381071410695075315482961522429891905381129320645/1047899235170633560739863801929205639611958070150694189488499584527041043137082563721218908614201921449076002548982308540689571766482794493357171683792336) + +(my-assert + (* 8957762734053174688386697837976422606/712105675122280831038408324375785815130945929819518342973925027507219300067 118977607972668646264715307919875588738/36563306353035936296510796886853084280648109576589600551753305930842020963283) + 355257727628119695756412145322380851760544279491883270008434507085780737076/8678979318410478400681656718586483785992423192579006235728835173903750764880944673586689792087386144715446501744012435157310426693657188196381455479987) + +(my-assert + (* 114386050140129336980347743358441052599/11994188887964574384037137314302737861703229337059619512751326848591488081229 -50822174853799566513638003084407139228/97406657802317796912648600328217961853548397771614449630742570869667560514587) + -5813347841057137571369557065847591420664634372223088557679866032754664253572/1168313852626327929522799656188055465298138284154709873285311568978496136227795809646907486798429717114923178357702460243511883684964123937654308495387423) + +(my-assert + (* -22147677230189664783449572410799931501/75580058176304394102183955194485040346816524663599269056794063928343401057143 -127672554664595215026114551202414743739/35777311684781371234035985601066874920871049301826919955489852676067316906014) + 2827650531865200718433745248471704607394596478050653604940563621773668622239/2704051298527551014378337257898371613519363350219566689647796093438747503077807722203668806231503452508016974614236112792032033672965127824348803574358002) + +(my-assert + (* 3468729773587632113679855593063165286551216344725198121609354788619580819847/7106612002452012151 20863200733446307102600190583661606839853255577505815215312643683864543217073/5700246487811068117) + 72368805556440529088812813715602124890901251289457147618293618526488567540302416253970205832659523238561757581481150988870947074663135867252252227647831/40509440107213064064897416415172689667) + +(my-assert + (* 43306673717838918980731699770600730039727453611468399058203483818093233880231/6173575908538565981 106634227988568775671050783423559067905086861634892257032833451008548321218936/17988169594879808463) + 1539324572884864883885215269788177741067901747630436643318399808029602335378536990210735234944615096105103848497832537965483619535769637171783464984418072/37017110149885307295697375341989232401) + +(my-assert + (* 61636028396239445662576777415312348317278054920190931147781159688109244233565/149659999183936017 50280832809996410949441105432174396823883728565382915986396125237655209339731/3406752842984125790) + 206607389257567119017662603624829733217835095238758046754428174885007999774491792658838812826043033826701244157167565054600950156595290052398436186551401/33990308513391731439280046802638562) + +(my-assert + (* -100579490802304807750359433955474958462342659278486016345156932756807754105945/15683759624513404963 7314396152134987983181095955389244247502417255088677055075146925285457081540/950287995699608967) + -735678240508074701153113537069655056596152436111651040530896921701439724727486696483134676487497031899584038731663111390949471467249259023050011663755300/14904088498613295322494450308817103221) + +(my-assert + (* 25984831699359211750216710442693374608159925357093100400945034699383345074385/10463598404993207796 -2395913226491242076662067669730978955981403048697660449593722338244504668974/7015215522730452775) + -6225740195664363384298636893730784883811595661227613249243163802476751022407971476247993440178871949687923603921101094083879668063131450147131783163099/7340439795432595812648347200273983390) + +(my-assert + (* 5173661857391320950903772549611256023540539838210520778403003347430938670915/2590493168574884173 100300641976357496491877756123729102910724064566692821682523911939220592349990/15304416107565779147) + 518921605664943617990486317157527087053001312760892500249127957517476408720600460633868004681188890038115877413554399588737851074382787744833707113540850/39645985375676570588146199684023740431) + +(my-assert + (* 30299639015164203561126609159677900559022306879488518544803392527841364186955/97638167801975054493877206805944332747 -50150465496280036231382225902610460555496341860773955714344071185921583266663/170117675960786609061777750278261277482) + -1519541000979732808188648781832621044050652591754537200855596768903085847105531546641139177813880505696192826380113425984545675787584857974943247950981165/16609978191541300835961154615181304582159561006676548938424954151558306303054) + +(my-assert + (* -34494394944257769716276791009665812125094062960425641316440943461722789694119/69239821080832171466311153221314488591 -68027404272124217088707268142523090163964888591405843143848585935878552833247/257149529774225346004390673137885895872) + 2346564149995340998782934409780604815295734898030424565252099571337345550054284934036215402972664245125313098735082896555892607540059632597741979943574393/17804987432587488254198543762235568841018786223139145264591718687823557996352) + +(my-assert + (* 22330754509472350470460807673039908304726422770752644988051418230315708975569/141163736844241522445115344332946835969 -3776092949566234532895208849184634613770861313997034923686862122594334787771/22367110097535579962848998753563258272) + -9369222740190326741203615957382420344247102784278353165345406236082475331042528539717966581690645628370939381978953360215380653092335198860022382107411/350824982641632215769272917522017419782283768012468846380070797128085153952) + +(my-assert + (* 1376215273451682681102140384578115142238259557166158859699272578561460124263/3593386179017642636485249017714833669104405991325015697577507088650274886871 37146275008876311604039415809582675415172661567487888072055609579242279390723/55424998453085285819414374477780690192979527887019008768378662580126754826472) + 51121271019052119686352858568900325361226598163234091421115939503875711782442415328681175322030659510284806538410228985354770913411724825992699509412149/199163423413390889071651575953261174839972499014963134990506980080139461063269751906284862132821075544766093817070661266293471833091996501160433036049112) + +(my-assert + (* -88175289711320073148300791156190227927348022787624424521937188958291199926437/38194742314758366741668899229532351990874883495690656157862650973602784662629 93421911195279228911508870033119580111709458306921869937709821511660370035352/66371395138592894543765954603571534463846496049156722497129962530412046587003) + -8237504085028962150049531747535213236460729066521397582683209771842938254589363802757604921456170821878391951762499073662677974506165863935238701489400824/2535038334389561782321790943041741331416028402594806464107449488311138037598457377927652600804722340759363172755193254192462811091332303758223034251210887) + +(my-assert + (* -88364214910455569163017945328431687038422451206033411348821431934742389780753/43010507830592044720656702803904712217809857004582018186125828892174875808576 10405170283887792832024806983921158923908589830001636723872220129826733402834/4055629711949631304631599195955105801456753694558712994574702123032807265321) + -459722351572673455425943766571506569631562018487574498847133029199411842205331593858852090421782204158679934054007027833206633183796877753882057444427001/87217346741895687976684378003169607737518608233754137677854312677618987931466495788077930577814677920791330694741284253568592140275298729115088619596448) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 13918288150951705093/1401140429528746218 8037346830653401534/12140087246062147767)) + (15 15819536596165521240797345101333717/5669989019487990500153722689252798402)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3027396677293618661/17394867614909941317 -2291333958125929004/3188627451035828949)) + (0 -3027396677293618661/17394867614909941317)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2672347537044132983/1242644867650938739 -18408840898134373335/10231522001278674776)) + (-2 -9204560351304414094275545654164256161/6357074151573303338260935869140273732)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2909960574201625242/1140661215026522267 13303037060238089383/18166352033245030796)) + (3 7340592943788470245594328177983578849/20721653182840810059519494723194734532)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8198662690782244017/1375380265264517299 -9940234650829186147/17690753691491997765)) + (-11 -486100547007747193780627302695509498/2211955773175772955922986386719257885)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3966139130172032305/18040321970861620778 152082737803043526/946729689784517957)) + (1 1011240112172972726360628393816617657/17079308423086645837394450304465310546)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 10199468022732280591/121419468943382552600797741323914786260 -2627475271750260665/95465240194344921114274153619846654671)) + (-4 -302411943986468199606823674581501024373007929237189061039/11591338766949818909386523271402122174353420293128216789558932652732995620460)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8471401573321747185/5927836485002954534423728282157030389 -10006560123550811854/209494971446104969537769985569938393355)) + (29 -54515717208483066409886298754350924985999966734110450701/1241851935162873209670541996670866824232223815534136678858726178724570665095)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3041516402669280559/23467966340832028705164128018098446335 6098690148519419819/74694157223362514640536233319542912231)) + (1 12008521321399654679364472921217933270209469640706386252/250417138224955291159963090840561809997874350767164909187205124534624089055)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 12371726101368968041/23093272201098893335944386552801821150 552920335555268471/59704833009801809998987650097493815639)) + (57 10833671498697672110331389655963519805471190684307179149/1378779960416507709477447168250340219220272308941040290894608990101550964850)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3936278768643199217/61530125725985401304656961990591319570 -4622522820386904221/99931589582562481620405120529601200875)) + (-2 -11699348415245273343366505594272785590391481515341739671/409920218067509498701508662179031915635595553469094563928706113041525908250)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3378221394828629408/57360271731094852990248264232533113197 -4121489923477642292/582636574825978160767401314647264235)) + (-1 -234441506605160102966099186988989055202999923102442904644/33420192252492486160839993475212088893408362946965395344436948483624609295)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3136864170660359113/44018155426864484368550814560728963265607376469242388043913852619483671810359 7592249764621265399/61218932554330370729612969835045191215382261653025522947071546902482986859295)) + (-1 142161354082922159316702479104046765633220994190482626315401062617857980099757409386379034462906/2694744488243248258380889922671073488004909384816885899374920518252041793957332742201117787314100221762775952924983170065632438581816845330037820256436905)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8388845076992722039/113324439625023255923060004687633012536810961583168953468887128369059333869915 29270787347930250/338347801532036561796340241450622341080868991428994657767799334610272208941)) + (0 8388845076992722039/113324439625023255923060004687633012536810961583168953468887128369059333869915)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4061469742865314937/64801603451247667482343238717974543532449298971352747107214551636724513855613 1344403291462061700/38470586305356068360716898225197866224089081322833216143931662358746898751411)) + (1 759644321951821493138045865317431182965861074290543254824595494322779964610920583206631767077/27395117343919593983759778902763691133722708413625034340026933459895718790907695509798551507285536033282436777270923749566119049487283571076783727846373)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6300876868463754766/63495830134457398131576869576746882401947668656296419431644557856865817622371 2683373787654434721/32958906466135519543294750118994566579246721224880398401534853634103601897753)) + (-2 133096081053989316587079956940067402118415059770888001584265696499152144351877946562766899046184/2092753126391210514581307904104631961415819403699771474276457943469530908829049497503906750315560161637143522534287446520082226490203274292567625907432363)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -472307136668592250/36283411370339306010717878389083492352344779970196813667782297535345620767127 -3180306511295187523/75166923119981694900512094733973876755239261156251968596129974579413418042019)) + (0 -472307136668592250/36283411370339306010717878389083492352344779970196813667782297535345620767127)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3148795985647001686/64429795462330994424525695145310698340316900821860011346129307089831843824641 -11298596415200487525/56650030835870774988744337125832477562271330606264442454925440669251648355512)) + (0 -3148795985647001686/64429795462330994424525695145310698340316900821860011346129307089831843824641)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -102545151309532699273956369870862301497/6030775709520909501 -3288683205470962892631604702141093469/1221554251153305018)) + (6 -348033375896483356529697355308057680498851424685117674/409273316984297575168605808523732001)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 262657016871433510082498751402781174749/7573480743368102221 51080528722906667824171406466289726452/1601607284756767193)) + (1 33815990969774126823949725673411671713268069951579559665/12129741929543448973808409847523235653)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 138482489784362691982393629835416135309/3631852344347114410 -24756007176022054565783765242491988918/219932185588761813)) + (-1 -59453406054861418860933161489781197608471921856017953163/798761223827929241442393231350025330)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -212217151846170123039362268732482984696/11596630494102963285 157767757347916893207763952109296030356/10257360923209581435)) + (-2 32941352246943117620876731374547894383947184420447916448/2643351654913607911070701558622724755)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -66747006612989726802598039638160699571/2655077042212383298 40811355885089157404164119163071734769/5571784139947382276)) + (-4 15382315863254661753182362315746357118308047043239937263/3698379038534340915097856546560906562)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 68762140087929702254258676232660238758/15300356027061891153 -35857327153107467171153230588794581375/12686181688605082704)) + (-2 -37488456798327399439537660212002603897618511901320984853/32350516076608496130809185423035152952)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 242045811640213090811968332747485173382/200549144102874156362839425688475328049 -14720899626826592765120758929463878529/55362986404688226126571951930830517493)) + (-5 -1360940123773119189782995319087829718305547957827775584170427519233923828279/11102999538439281856672090511521389719230333671905312848993361013013608061157)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -119845294654504250162135973476212065855/100235561394484311088266800183679226574 80594461105267736432364594799413149425/61631997559252488378599155330559465978)) + (-1 173031536634535211165479230108382118112369885610634326444128663790131209690/1544429468803790002857581373808877159258315141389178393568445604388376624843)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -230485693234637510798211679560546639349/52735224446003804525152654032694494673 -216057981617610709644611545583688426965/260006637986112259187147152181319007048)) + (5 -2958479432060194175681245276352090941756054532611547690395592385359334844527/13711508411648488620980405764270377927416829995446554240961159998044485455304)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6594316542549343232263525515993767282/10217421010314527320204876001269664067 150738011702184633072457541580514087744/135040956724953232085930818414328999685)) + (-1 216550304321963092517168155612888510209814057236150214483836375316700196226/459923436164837338339599279302608001719626738369225259576013169605366272965)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 215280935061082631947114960623303029323/207354325693067193327551969107966799241 79751059907103262336474674983968289237/4337760464235769010513178238272088134)) + (0 215280935061082631947114960623303029323/207354325693067193327551969107966799241)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 310160128112311271225164732000676894965/86670395306350722800942425502835485142 178141651878134061724955020964246844473/148821875093870378260620578385076958277)) + (2 5093132355806944300558276298272344941234347692198850733707837927916021244991/4299483581539365588748720077960621199296398702837049138084337644406995806778)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -108659820552054791199784298344597956614/11790531032698157780195997261827578010352156078055016836768011974016954903741 -92538322534416259700833065660026629223/19585963177324586927996277066630337817907750129846119872015696245293090497388)) + (1 -1037131280631376361623284528995684848351041247146708940120596004521550738167239284685366257725745514224913041700989/230928906647528953486003129436653219142752591225509660589870619206780147714239888278154624266956202529317853226309156501996262035307639197627615351928508)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5394706491096230323847274166255447931/10999333470518091906908673737442830723710024941373839628113269063387717150756 105688652677006186461732590041930264063/21972728496093720326374563200555762299989227113998910666496198593694363180514)) + (0 5394706491096230323847274166255447931/10999333470518091906908673737442830723710024941373839628113269063387717150756)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -191689412702065586724423672263415136270/93810201821180445246181740077575222573046098171118578720996957721548578622199 -96035306478379345278597023485459703599/90477882577875726723065337577743037040931870384035502080606137411367114071296)) + (1 -8334560691183765714134253806956288712175511004636349604358505688696669629914037375584956898475941052209595993911719/8487748424983587977143569651002086894691875550521839392659856872027244953584789975128015403703285861633097358090901236825413778659897331594626425134299904)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -23269937861894460494044792238228308465/36609152344338882339480850660297061488131282119857763060331849352205685148721 325068909216594106686082320524489871331/91177237475655724082435461235746167562462517272459785633509544221351873775622)) + (-1 9778808569440655820425835535754928474979020881405653286273845718180424961228320899578451645656486131670752875977421/3337921377082244749772660717107363339434489502423902307989133990817960972244485458695718522007125256227586389900645261310720433804087640398154830854279462)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -238326953836192259685740729837504392751/14355772111692545517089448796014758311054554297101342377064555342044509505629 -2243842813596041779461072557214411973/26977869328891440663623277939723739398284518432434090329689171706564354694000)) + (199 -6448765647740977471904737113847651808330060639815597135148713750030489976324569684096986913258458168828297495539/129096048048195144296601029799754739460578975322841318685536300111243981862070688561642588911885232705019881753766051653025282618058049676501115190842000)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -154358049055187385619395426022892405693/9651466522903571511806795329901971873531573523740147689205585933143787251744 234831599528611417562275088467151900111/23212020955553784427152057042945842586938059290340162186208579138883161355663)) + (-2 316658791137724604029754690574124702890700231484127998714230110560397057808441246896564869593555547226559779365903/74676681060487840411987924431521223169933844488425876950176937169482763523750924018302125631058404128587876741120722730563623397211887516476096033675424)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -43654015885600226452139253734240763904114948357839504394635758939147918485226/8959421350865475053 -71396498978827369985021009185210519228191289633806094987720268011017813959395/5118659875263168828)) + (0 -43654015885600226452139253734240763904114948357839504394635758939147918485226/8959421350865475053)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 30206748063040753946799836869317684942154090322823467523870425873885298155111/10481539418044277488 47024848487236673350978260730205414416590483746605328718368229684499622280474/7191921838593099535)) + (0 30206748063040753946799836869317684942154090322823467523870425873885298155111/10481539418044277488)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -78297878369391722158254897331818780133560455296543117876032852961696240531334/3439835335342974343 -12036259456916995957158314961009661904873237837146662571140339452059150719867/7648180594799196815)) + (14 -19197805765101853520494699712598051602631126933023081616555585309855479307669655742300981287876/26308481861074724148503061769552317545)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -11644466368871135752271367372638717312589950278007329817169736850185519100737/1311440431008130360 16666792145043036974187190230561351375866940864814143604767927371030164658327/1190204555866760523)) + (-1 7998208151350462202845967149504108047636942539158206705970028049633264098721802988652183702269/1560882375733744790369742288085778280)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -79973663368880337215592714973251653953011156710750446016524362581184906490344/13217906252057303539 58550120458525994168414457422879483045080411293174816365332363703279727325517/11983119832054095608)) + (-2 294743007488634911900879023610601157709203210196036764662698142539282328840165292825377976700087/79195877273629847756913363266891378356)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -41283916983957018057492477658728498328100012640087810269690534262888976961251/890401703093780527 37905097813993829793947873722213455441729327992618875876994782685865871567157/6801392244603328629)) + (-9 7656253348038361960592683452946138937700391767097248361228404271354846832369355003597180736924/2018657079334544839920956083927269161)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -18621387073793741287833632061282985993236184599525107084971126746444001531559/112377251064249742125143336262406044187 -80344252057643577515390451958447799739023169996897035042227858478107352127859/16565237077789941458934656364080562722)) + (0 -18621387073793741287833632061282985993236184599525107084971126746444001531559/112377251064249742125143336262406044187)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -11067278490740390186400140048488373691939192899502978554850454064301747327289/279730468938850077684950205987597341304 10742600231685337944302634339424380376867728558611903252501449407612160123471/85514692364145379323997472383947484080)) + (-1 85775736874497976296219552104494263998937714945890467644689458878788010379480929901293727971077618208617170461961/996711041507662039484243506170638972651237308243642442559705598573661101680)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 60114400703399744178227904113253512958642740092037841351403601970012663733574/137652538688206271590219421417082587275 48818636606796573849225811493965362933035106650390076441334389457476994620122/53029693036557887125608655547988906029)) + (0 60114400703399744178227904113253512958642740092037841351403601970012663733574/137652538688206271590219421417082587275)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3914498366778062569843980805049542971189141573995351572704819538012574198620/2893535793927099250376915741311683101565016171163532500028982710856616653543 -64455977862771995990556362474021252617135665526576459531278423102067698175925/3427268293660091333898426457103031174054024747619806545506815375759964110507)) + (-1 -173089642940460836493548201378493831666834527213381638819285816422714170656111775323359444521902045952676537769939820706047335458029055584112252141651935/9916923483096927116177052980173451074387932639677487416966276325060341893415045555506102924285291258490295955820662010134773377007870870750288985076301)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 88685468991633001080737925907185943038820418099572822599681084512202985499349/12356339561700478684701129356342132279853496560835988907745653698832814553183 6529471572210817352014560971376587702394496047549533959161274051805568907/3739659250056306079416159597801009351379164652345884310988690700223397485)) + (4 8931962841313470806790103494237286341563410404854617106114803081793820819240374925219641539537617481113314045913411523358730270170471325648745013341/46208499538749877879324553712339970407875860449933229680283463405247211324108302788607460717099015088790299594129098751336540918286885704752480944755)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5294621876959552948152278397535786930445255402598688035901577017296377116948/5881250468392395166026135319241737823103911942970361556821993967308880332607 -65630221834131781450865541487035630878349246622282004360445526978282263449249/98696808137715829282209856003081855629375417101578635063186137762415694777903)) + (-2 -249413266253338816038191146071217173249587815937933968995202267999853691656986532179554523041282106904325952906300316562845535251623832095499430051524242/580460649088775579832453445973177920831893989101100068436102498480125976298386547626652311003668489010795846489626845062951616643824353457996671633983121)) + +;; ---- Test von / --- + +(my-assert + (/ 7013212896988366906/12397903473277899947 818833870013215068/2125577647443895255) + 7453564285301859120853045020886215515/5075911640537211768265804260348400698) + +(my-assert + (/ -15781329068048599432/14942574238341613337 4388772934226358350/2640112802717985697) + -20832244458230302534551181278529162052/32789782692450857054331267544650656975) + +(my-assert + (/ -9015230453321124271/17425619133302730035 -10422000746814766599/14972344381173680534) + 134979135022768387806775446187867640714/181609815620990738305316999098032100965) + +(my-assert + (/ -14741075237791868512/12448692140900938227 -1090381863721238817/1060836378253796023) + 15637868866825840780217685066084527776/13573828137487503515304766902031557459) + +(my-assert + (/ -7371815071140740177/4722722556038701367 3872455829192658988/994203944294825175) + -7329087620340161131469364260313555975/18288534491791723206480607737200436596) + +(my-assert + (/ -9856364379969390509/7988230468709836259 -7208901117187058135/7430860779232874136) + 1093153305924514768551484985555671272/859497963436269188803272225817371895) + +(my-assert + (/ -16740689272507881147/56924866550406451570641164619431212169 -14712532880452686095/143481612520580129383584255576273223983) + 2401981091525408257128502717450566513166280001357873948501/837508970838236191644285394369194561392491093277901090055) + +(my-assert + (/ 1874027699956565000/65960003455647360668413772300355814843 -172394881832672950/2006879686300828197846469567507151887) + -75218962452157875130617756878839223573611935155763100/227423340028380523596387094039260091189651621559491937) + +(my-assert + (/ 851521912886492079/58839621451933520132430725102159653727 -5525838657334730480/268863138354222710211869290179088409033) + -228942853876053297959532391872114722003932597144466549607/325138254802036127673497464266072288930584674567672498960) + +(my-assert + (/ 2130823024472312937/30463932363736038600114358208342163020 413938864244113775/131673792970459944919771618253738144891) + 280573549781056638388629087822719475587456644826399754867/12610205563054396144647765193069861697742251186477600500) + +(my-assert + (/ 17234694073181371137/253506951459931119968572673772742357160 8407879684613951161/42697666588937447817581914537644794355) + 147176244259806896721181660841298454615950364713859506327/426291189417673978158704851675227114861497071554451732552) + +(my-assert + (/ 14739301038477826821/4801125431810347467140397350459581435 -1752125940488995048/127905197451270157484305628763539243969) + -1885233209620217720514367144506571751170505057476450692549/8412176412616337518572109406238500578932979745867733880) + +(my-assert + (/ 9194848570227974720/45448499872046683203864930109076126035374684748838016011669264943000310475483 -4572473918523931944/28941042619577200519536336906341131911598596429670188136734086846500956354149) + -33263563043940787786171015409141766453199063320923723716765930467953050399983260590187417389160/25976510037621464639740779963549572814837984766154635046133743883024710122710674726552171566119) + +(my-assert + (/ -2662376868940711929/2674240208804755702377222409224408783678596883960539287029565653749020338064 -5046618244273151929/26826013625152995057141957222948811537350409769204161465077735924332004069058) + 35710479080747854012875521001477955195584454274704368888444222736697434540936425667291700196441/6747934713661461716612153292457811722283965560031580498434684530869001786777260513409206862728) + +(my-assert + (/ 646980248518054663/28444849537262537816809349756569888989442483441699293309597267649158853799707 -10174938507557455325/16470612178414296088079890015341965945714023680627341561729034923083435428747) + -10656160760434978971303471120231114671340660575734505071429575384684610862775940451177787597261/289424594898370460244167952344748286246980979584479610186308309369583658143095854438992150589775) + +(my-assert + (/ 1268676597518744714/6024937921458004492480888468749320142603908196076058575752452561172018490893 17823595902143962912/85935047374548136904062562443188289405155329832270007415035044821925251080203) + 18170630585125644385503771892175817370913744757273904248648000044618805359154885235028182716157/17897676474595109057512045856227678061218241143085827332930191066967148125532813505892133626736) + +(my-assert + (/ -3035741006152688190/58890268425224581569217175195410848521985674465189565646495474378301884202047 -4870935665435665519/47998868922405332801456101880162843269583282603435159879276723163289928325531) + 145712134636693761356266465698326002831562744975420904782663360472436650653549187025441059178890/286850708819506259357726384810790881448875152111132928069815447961129371272624891025817707117393) + +(my-assert + (/ -4420263280205408439/38682162086456801604593696710774835436326970692840048042132553053971380151628 -758651402628235427/1755534012040040367913026343944696058732638465867705260088080517539506722166) + 3879961265286134914514096239640695384126081133972137242327715997675029567458817030555062379437/14673138261791601182714628661554161812345431143865809776872034934342213839184709418896670662578) + +(my-assert + (/ -312487180249669742743295380499853180353/9828632991038934281 -86131955660561774942466932680637336739/10268762916730341592) + 3208856768501438660232746468300370677374054716853273141976/846559380988100144557815474234956961169507773676687849659) + +(my-assert + (/ 105376075880566042097567073713047434893/11411565636673693365 -220737802783327232867818580441304577024/5817406274606660773) + -613015445021032499619145665530563205764250055719854552289/2518963924957071797477174332253152325843619212749200245760) + +(my-assert + (/ -311533429150518992652072799089375050497/4403073054828470603 -320230219907951760832723580313293021909/1370493254961533625) + 426954463345823097468320537904981772054351338526938461625/1409997052618498081840381197699863669488222338862641441127) + +(my-assert + (/ 305676222727436457375950609916137360009/2001517485431820526 324338803123828318219640932070020543912/11123178903397935211) + 3400091311912189654145957985944153094384781502787164376899/649169785656371151621897383467144093766684841422885937712) + +(my-assert + (/ 8845112929712368402815105446090151026/8124751572615311799 -107609110538267962880281203537194473336/8714443449141779053) + -38540118213625599008519681983731393728094066419546629189/437148645036763776481446937412401903340367189496615845732) + +(my-assert + (/ 152921217721894690043853278309581658066/11705615305395353865 184187448038871874764725486848823516773/4171619104693691390) + 127585814672335876029018138907883882524550368713261650348/431205482165106014329333719781838993214328411764819575529) + +(my-assert + (/ 16414254293541341780725162107696242521/155838132618727968561620486302365154071 323320173010032367023620851618405869489/49801924105617352177018959505967933104) + 817461446577249670665800625691379410535771218196808189195363718417488315184/50385611999847495177988476252475899813264458225659097815552272081452203039719) + +(my-assert + (/ -188149667625860588508273820953820709614/21438745582767797684161462130971215025 128458309657689922121539794960212789849/134174286369366827879740776978166655691) + -25244847384333405496229128525982900130397411994350175944375943735942831513274/2753985018743617742875555653653797261370358442640799457019039857068516281225) + +(my-assert + (/ 1218460641064115152742257147372113443/1773382194117714970762642066492794929 -105212349758139121832338365854603836112/35045896682356785176328011712384921341) + -42702045738251194875426595475683618047253961691478453648029952948483687063/186581707662369193907913729212042024270164277319717456729276609131940676048) + +(my-assert + (/ 1467722271775252460214852151179762687/1747611358981474614363356529179985509 25495740211005247928144692929451604259/29615224810946461612486375021101910565) + 14488975012885720730598332784736375353299643425098519766594278819666029385/14852215066131169889445443721709162270198753408805825268529301698140894277) + +(my-assert + (/ 6278399735526726207674375684072448068/13890681759576280617381650633747782321 -112063146811220963294237186476216238443/46495820670393894026441353693945662660) + -291919348200099113895651901892723884699250237261456280525601785996696740880/1556633509331345870779770006255469001211806559199158615405344674499795966203) + +(my-assert + (/ 248406099260780863433196593538936526373/315762135750029127758352280023694126018 -24578051912523675039725210046249323571/3033769619337997374435389027823294736) + -376803438597807975522050212312559316811899647514236724224019181136008036264/3880409082236781853269738100403484871805889674074731389226471480469265885139) + +(my-assert + (/ -305871752543087256004326578375555909668/80170799467978436032303243749692785696371676780847080230403479135749775915991 -208573266832391890136462745593008906685/96016271562601269514856687672805175650907293023094157826925793080307407361434) + 29368665255505841438632782694581946057561031972462112644657516768267440383833513431444679871238206541553985530943912/16721485549600848123731461311227384049611071114404954309505697259277905994635125654414916826332204568970567318299835) + +(my-assert + (/ -171651126582338417143004525987733942986/48126955023093310081685702171788275811688444573315712039582092051531229683107 32570134112026732491936310765048378699/18584159151613423191553551933672204731023422884196280183931777685641069715348) + -3189991854959918631828923606391779823799241149346421336570141741355492000935500642040047513113849334779592681149128/1567501379505627719887579027549074087653888429037997616626567546431482074522690424133509833932668944596793898937793) + +(my-assert + (/ -31304786393644787215292629624842492472/10539846271603297974613179098685212701091372728582260780054561526149580513583 43496364289252206338797704034889660065/966865502932307025364733802774045297740949567802356684866342045679773834966) + -30267518040679809082934454680954168768135550720881039440573156734314284479043791824457029301083428211405425375952/458444992982373700837242411005687390212275114474481688646320865335043970683786989531994936463047685893258985162895) + +(my-assert + (/ 124366625369659591476708994326732418029/107684759001536292829359995221778346870065030877016948429894748600664800488759 -90949754058598173499067700725927605729/79727020098830307921496202496061295138733611655702270828135321391380898414003) + -9915380440470549523296226431396644117384598256053664887332801972488440466568616812942647849957495261151611303260087/9793902347049141646079571573977765974008832433473016883117384010293158932212528563016145547341801740792289848500311) + +(my-assert + (/ 26792084925762094333829722201654015569/6815899891200140342329613369008754659665480100088941978786466272502677117648 179968988142253715757129058636648023126/97033837835570527321466682927970125702018459951415339098532052222053589117353) + 866579607987744230609336186273867662887766686833260209925103055244528379635362816895584608387230956963010276689619/408883535566062149539621907018509777969515872715944952500700527207173412646715462423653890585029605025758308909216) + +(my-assert + (/ 320794852821756057819990044473359503428/42380074203350930293358543616207018031675687905746455222111844144668904183229 -11813439835454851567822019323728871339/51852159737956631156972450987013128151750117741949546305537111598356497409240) + -5544635317209327550045071802859986261979158492907374734760649234578367469399038563605323839330681533705071632958240/166884818941132804535892580774781586387104334774784737031184369589400544303785250219152004898392301479219940857877) + +(my-assert + (/ 63160395612932962868082774785156358041658469338654564454114468396132462549944/5671929772244157797 19541045450680948617094710246839287171374470593288265457341382295544977156173/10827756125123268218) + 227961786821047895774887365257727015864174017882302289602409601101722343657899277052494444293264/36945145824164509580938949252327087600266044162541122809277442696583642758457532273140841543627) + +(my-assert + (/ 31389399613343712511677734270541516183531975055644318154870016415582858008412/11320913214023484367 -95931706646769408081251897664360951854776052790951374912970042200868629796051/14301831604104230477) + -149641969141325406602881756591195860220337618158488775091717625369334526143115090325362684257508/362011508473745439254610688691597507367516106821889963803421575701854031622412859179610532278239) + +(my-assert + (/ -50845041077039215658764589763556935122444212169574762080162289087527164772395/482986173890811026 -51342299909113507561385579724776151277474630060658338514843664853027455595538/3864573616937705869) + 196494404298439669659681446421686066898686292162412914850963937042669022612531239234324840686255/24797620991857267698917294149872672843409173617406514673128342148521539559341861421304646801988) + +(my-assert + (/ 76283614020376921713154299810619585257752996149145061806263596894412414185408/337890011287912517039286436540240936661 70530558237421368381589233382700323659036925075366138096846582768833233488577/12121510300837787759729092713205686989) + 924672613133132744522463879340347327755455994321131972145048214329608890428265966744607561005512244129921459256512/23831571118985077324412202325831974453532679575894228007993082738742295289254461850021038245882565939546151124021397) + +(my-assert + (/ 13518475961402756750057330871273933874583566313800024119371308450919239424622/71146816100737230880567880716110051085 -11914742388051168959634071864657967837347162591767656949770878950409478930980/166466796775669753065110807850377519909) + -1125188695291804746273664719520877594103080002716204716437885631737502681157239448228517736957154781558316254899699/423847992785167635691798025732868758201476408654527740579259436528169254792708107390082891890404030666159494556650) + +(my-assert + (/ -53624051286117226406327700847140806598091981633622544805551583455315188018537/149060170957501829683988930330276188371 -49540630291338976658332195799658601133012561780540500265134312414843218811481/313014990314092319823049811442768272842) + 16785131893926373429171158665038393627227592608630727377590747943991201054188961463248027101037470630205119769672154/7384534820569381535972144752572408048556227885764547207137140227958732266609348654686668662110083737942669493487451) + +(my-assert + (/ 2634758410586745842739353561704344884865889793873131750193619887157306355755/83106075320614705363810122092414199463231740446254118542567688658288107572919 10787649314660479714744029413883607304719873485501736976813666398631455642569/2439964488756696481271244145022481444549967702052558191280867337292105066432) + 2142905652761565172685487282499186838096673751132490328620490049367034561455889328384026705096013173825469773464105722689198047146574263705663366838720/298839732158850477765824602476778580028064205733214070073086531571837859351705342746223206218407306637658483098569582239416197836311325170250187389329637) + +(my-assert + (/ -1907320079310938642409293211056905401889419041722087613680756850005726714712/10387378553621846874105702088597026076825105075730032753153301604042569998683 113647247724474559442709588703965365251731833799417671287796250968092484717057/58756890421232187224353930678527831208703723187770044891160428018937233424397) + -37356065632762902117955690133395145368676268194116097031480521390942668514422835237280325034441435052929702455487858500299401976652159912902024146542888/393498994563785425899168694480259206994308562177080555315323154941891277193612821825931878224565302417504072329241812530787363937691786269618438039211977) + +(my-assert + (/ -54987418627898620923060954379316763081930842855917193391807940070173620336071/17370345837184638879794373707261631548922174314274224219546763452439685451597 107349939397731511365417710412808670916754334908520065561311453951414109180973/7800708635318451621630266369706695626474649690647985662113853436261704078874) + -428940831324519456770429889832838610542119304716244392653623661175655561457214418178921042544524225772650432309479656622489393939407340321261255371264054/1864705572939408818246392762570376592749103793151936455808919833872532407312841098160841844995663367019074328670998871082130543124576872890789577304863881) + +;; ==== S H O R T - F L O A T S ==== + +;; ---- Test von + --- + +(my-assert + (+ 0.52019s0 0.98203s0) + 1.50223s0) + +(my-assert + (+ 0.026268s0 0.6137s0) + 0.63997s0) + +(my-assert + (+ -0.338943s0 0.450523s0) + 0.11158s0) + +(my-assert + (+ -0.032799s0 0.995186s0) + 0.96239s0) + +(my-assert + (+ 0.249222s0 0.96463s0) + 1.21385s0) + +(my-assert + (+ -0.46177s0 -0.80114s0) + -1.26291s0) + +(my-assert + (+ -0.127754s0 -1.88775s9) + -1.88775s9) + +(my-assert + (+ -0.65572s0 -9.1112s9) + -9.1112s9) + +(my-assert + (+ -0.99359s0 -7.6134s9) + -7.6134s9) + +(my-assert + (+ 0.0169907s0 -5.9027s9) + -5.9027s9) + +(my-assert + (+ 0.77272s0 -9.5384s9) + -9.5384s9) + +(my-assert + (+ -0.50671s0 1.95366s9) + 1.95366s9) + +(my-assert + (+ -0.281487s0 -1.4109s-13) + -0.281487s0) + +(my-assert + (+ 0.86259s0 -1.8225s-13) + 0.86259s0) + +(my-assert + (+ 0.42874s0 6.326s-14) + 0.42874s0) + +(my-assert + (+ -0.53545s0 3.607s-14) + -0.53545s0) + +(my-assert + (+ 0.63671s0 -4.723s-14) + 0.63671s0) + +(my-assert + (+ 0.34449s0 -4.873s-14) + 0.34449s0) + +(my-assert + (+ -0.480698s0 3.03292s19) + 3.03292s19) + +(my-assert + (+ 0.85132s0 -6.325s19) + -6.325s19) + +(my-assert + (+ -0.54742s0 -2.83806s19) + -2.83806s19) + +(my-assert + (+ 0.45269s0 1.62964s19) + 1.62964s19) + +(my-assert + (+ -0.5122s0 -3.6148s18) + -3.6148s18) + +(my-assert + (+ 0.192093s0 5.3618s19) + 5.3618s19) + +(my-assert + (+ -0.43486s0 -8.918s-24) + -0.43486s0) + +(my-assert + (+ 0.289955s0 -5.911s-24) + 0.289955s0) + +(my-assert + (+ 0.274345s0 -1.6779s-23) + 0.274345s0) + +(my-assert + (+ 0.392723s0 -7.441s-24) + 0.392723s0) + +(my-assert + (+ -0.62215s0 3.521s-24) + -0.62215s0) + +(my-assert + (+ -0.5406s0 -7.718s-24) + -0.5406s0) + +(my-assert + (+ 6.5444s9 -0.060898s0) + 6.5444s9) + +(my-assert + (+ -8.541s9 -0.181755s0) + -8.541s9) + +(my-assert + (+ 3.02993s9 0.694534s0) + 3.02993s9) + +(my-assert + (+ 9.3926s9 -0.77226s0) + 9.3926s9) + +(my-assert + (+ -6.4481s9 0.252235s0) + -6.4481s9) + +(my-assert + (+ -1.1734s8 0.94104s0) + -1.1734s8) + +(my-assert + (+ -5.1049s9 1.28059s9) + -3.82435s9) + +(my-assert + (+ -7.39554s9 8.9347s9) + 1.53911s9) + +(my-assert + (+ 3.11457s9 1.71478s9) + 4.82935s9) + +(my-assert + (+ -8.0461s9 9.0508s9) + 1.00467s9) + +(my-assert + (+ -8.58006s8 -2.82289s7) + -8.86235s8) + +(my-assert + (+ 1.82954s9 -1.83914s9) + -9601000.0s0) + +(my-assert + (+ 7.6292s9 1.3988s-13) + 7.6292s9) + +(my-assert + (+ -1.43837s9 -2.482s-15) + -1.43837s9) + +(my-assert + (+ -6.4696s9 -1.3269s-13) + -6.4696s9) + +(my-assert + (+ 9.6744s9 -3.132s-14) + 9.6744s9) + +(my-assert + (+ -1.18927s9 -1.9405s-13) + -1.18927s9) + +(my-assert + (+ -3.81462s9 -8.602s-14) + -3.81462s9) + +(my-assert + (+ 5.5761s9 1.32286s19) + 1.32286s19) + +(my-assert + (+ 7.1631s9 -9.3184s19) + -9.3184s19) + +(my-assert + (+ 4.7921s9 -5.8008s19) + -5.8008s19) + +(my-assert + (+ 7.792s9 9.7695s19) + 9.7695s19) + +(my-assert + (+ 8.9575s9 7.0198s19) + 7.0198s19) + +(my-assert + (+ 4.4688s9 7.2066s19) + 7.2066s19) + +(my-assert + (+ 8.9222s9 -1.3243s-23) + 8.9222s9) + +(my-assert + (+ -9.7717s9 3.434s-24) + -9.7717s9) + +(my-assert + (+ -4.22478s9 -7.938s-24) + -4.22478s9) + +(my-assert + (+ 3.9261s8 7.916s-24) + 3.9261s8) + +(my-assert + (+ -3.239s9 -8.986s-24) + -3.239s9) + +(my-assert + (+ -4.6268s9 -1.0129s-23) + -4.6268s9) + +(my-assert + (+ 1.1171s-13 0.73372s0) + 0.73372s0) + +(my-assert + (+ -3.575s-14 0.94588s0) + 0.94588s0) + +(my-assert + (+ 3.176s-14 -0.160759s0) + -0.160759s0) + +(my-assert + (+ 5.055s-15 -0.0258102s0) + -0.0258102s0) + +(my-assert + (+ 6.371s-14 0.480484s0) + 0.480484s0) + +(my-assert + (+ -9.257s-14 0.698975s0) + 0.698975s0) + +(my-assert + (+ -1.0281s-13 -9.4453s9) + -9.4453s9) + +(my-assert + (+ 5.960s-14 -1.71395s9) + -1.71395s9) + +(my-assert + (+ 6.805s-14 -5.8515s9) + -5.8515s9) + +(my-assert + (+ 1.1645s-13 7.4758s9) + 7.4758s9) + +(my-assert + (+ -1.0064s-13 -1.86868s9) + -1.86868s9) + +(my-assert + (+ 8.912s-15 -8.4908s9) + -8.4908s9) + +(my-assert + (+ 4.036s-14 3.308s-15) + 4.3668s-14) + +(my-assert + (+ -2.503s-15 -7.642s-14) + -7.8923s-14) + +(my-assert + (+ 4.653s-14 -4.612s-14) + 4.10262s-16) + +(my-assert + (+ 4.700s-14 -8.456s-14) + -3.756s-14) + +(my-assert + (+ 8.181s-14 -4.658s-14) + 3.52305s-14) + +(my-assert + (+ -1.5467s-13 2.3608s-13) + 8.1409s-14) + +(my-assert + (+ -4.341s-14 -5.14576s19) + -5.14576s19) + +(my-assert + (+ -3.159s-14 -9.4925s19) + -9.4925s19) + +(my-assert + (+ -7.325s-14 3.49983s19) + 3.49983s19) + +(my-assert + (+ 4.134s-14 7.07955s19) + 7.07955s19) + +(my-assert + (+ 4.080s-15 -3.7832s19) + -3.7832s19) + +(my-assert + (+ 1.1577s-13 3.30522s19) + 3.30522s19) + +(my-assert + (+ -6.838s-14 2.739s-24) + -6.838s-14) + +(my-assert + (+ 5.050s-14 6.768s-24) + 5.05s-14) + +(my-assert + (+ -1.9477s-13 -6.657s-24) + -1.9477s-13) + +(my-assert + (+ -6.348s-14 -5.222s-24) + -6.348s-14) + +(my-assert + (+ -8.770s-14 -1.58234s-22) + -8.77s-14) + +(my-assert + (+ 7.906s-14 4.9202s-22) + 7.906s-14) + +(my-assert + (+ 3.7985s19 0.8199s0) + 3.7985s19) + +(my-assert + (+ 9.891s19 0.79037s0) + 9.891s19) + +(my-assert + (+ -1.49583s19 -0.360153s0) + -1.49583s19) + +(my-assert + (+ -7.36023s19 0.8185s0) + -7.36023s19) + +(my-assert + (+ 3.62075s19 -0.364594s0) + 3.62075s19) + +(my-assert + (+ 8.0477s19 -0.531815s0) + 8.0477s19) + +(my-assert + (+ 3.62182s19 -7.2661s9) + 3.62182s19) + +(my-assert + (+ -3.23868s19 -9.6806s9) + -3.23868s19) + +(my-assert + (+ -6.08735s19 2.89138s9) + -6.08735s19) + +(my-assert + (+ 5.00175s19 -6.3548s9) + 5.00175s19) + +(my-assert + (+ 2.82944s19 4.7262s9) + 2.82944s19) + +(my-assert + (+ 4.6168s19 -6.8772s9) + 4.6168s19) + +(my-assert + (+ 1.15555s19 -3.786s-14) + 1.15555s19) + +(my-assert + (+ 8.1897s19 -8.971s-14) + 8.1897s19) + +(my-assert + (+ 4.32734s19 -4.794s-14) + 4.32734s19) + +(my-assert + (+ -9.4559s19 -1.9717s-13) + -9.4559s19) + +(my-assert + (+ -4.20726s19 -8.657s-14) + -4.20726s19) + +(my-assert + (+ 9.7697s19 -3.376s-14) + 9.7697s19) + +(my-assert + (+ 6.09264s19 -7.5608s18) + 5.33654s19) + +(my-assert + (+ -5.2828s19 6.8924s18) + -4.59356s19) + +(my-assert + (+ 5.73685s19 -1.4978s19) + 4.23907s19) + +(my-assert + (+ -1.30897s19 4.8593s19) + 3.55036s19) + +(my-assert + (+ -8.5586s19 -9.712s19) + -1.82707s20) + +(my-assert + (+ 3.8772s19 -8.6355s19) + -4.75833s19) + +(my-assert + (+ -1.03845s19 6.88s-24) + -1.03845s19) + +(my-assert + (+ 8.4716s19 9.614s-24) + 8.4716s19) + +(my-assert + (+ -4.3023s19 -7.649s-24) + -4.3023s19) + +(my-assert + (+ 5.9593s19 -2.552s-24) + 5.9593s19) + +(my-assert + (+ 9.8934s19 1.3093s-23) + 9.8934s19) + +(my-assert + (+ -5.70567s19 7.918s-24) + -5.70567s19) + +(my-assert + (+ -2.893s-24 -0.93898s0) + -0.93898s0) + +(my-assert + (+ 8.795s-24 -0.030014s0) + -0.030014s0) + +(my-assert + (+ -9.366s-24 0.200493s0) + 0.200493s0) + +(my-assert + (+ -9.3102s-22 -0.28704s0) + -0.28704s0) + +(my-assert + (+ 7.142s-24 -0.45701s0) + -0.45701s0) + +(my-assert + (+ 9.420s-24 0.957794s0) + 0.957794s0) + +(my-assert + (+ 2.975s-24 -6.84104s9) + -6.84104s9) + +(my-assert + (+ 2.26822s-22 -8.9898s9) + -8.9898s9) + +(my-assert + (+ -1.531s-23 8.1961s9) + 8.1961s9) + +(my-assert + (+ 1.7221s-23 -1.53725s9) + -1.53725s9) + +(my-assert + (+ -9.488s-24 -4.77676s8) + -4.77676s8) + +(my-assert + (+ -1.5077s-23 2.8251s9) + 2.8251s9) + +(my-assert + (+ 3.410s-24 -4.701s-14) + -4.701s-14) + +(my-assert + (+ -3.361s-24 -4.947s-15) + -4.947s-15) + +(my-assert + (+ 9.026s-24 7.353s-14) + 7.353s-14) + +(my-assert + (+ -6.385s-24 7.789s-14) + 7.789s-14) + +(my-assert + (+ 1.8237s-23 8.517s-14) + 8.517s-14) + +(my-assert + (+ 3.4439s-22 -4.345s-14) + -4.345s-14) + +(my-assert + (+ -6.817s-24 -9.8611s19) + -9.8611s19) + +(my-assert + (+ 6.213s-24 -2.7257s19) + -2.7257s19) + +(my-assert + (+ -1.9353s-23 -2.71446s19) + -2.71446s19) + +(my-assert + (+ -3.653s-24 -7.7565s19) + -7.7565s19) + +(my-assert + (+ 1.2298s-23 -1.56532s19) + -1.56532s19) + +(my-assert + (+ 2.905s-24 2.334s19) + 2.334s19) + +(my-assert + (+ 3.182s-24 -5.727s-24) + -2.545s-24) + +(my-assert + (+ -1.0745s-23 3.640s-24) + -7.1049s-24) + +(my-assert + (+ -9.7145s-22 8.77s-24) + -9.6267s-22) + +(my-assert + (+ 1.3734s-23 3.225s-24) + 1.69588s-23) + +(my-assert + (+ 2.745s-24 1.0505s-23) + 1.325s-23) + +(my-assert + (+ 2.780s-24 2.747s-24) + 5.527s-24) + +;; ---- Test von - --- + +(my-assert + (- 0.57362s0 -0.0545654s0) + 0.62819s0) + +(my-assert + (- -0.121063s0 -0.157204s0) + 0.0361404s0) + +(my-assert + (- 0.75334s0 -0.186554s0) + 0.939896s0) + +(my-assert + (- 0.879036s0 -0.54558s0) + 1.42462s0) + +(my-assert + (- -0.245338s0 -0.003891s0) + -0.241447s0) + +(my-assert + (- -0.89576s0 0.61608s0) + -1.51184s0) + +(my-assert + (- -0.59227s0 6.61s9) + -6.61s9) + +(my-assert + (- 0.381363s0 1.88003s9) + -1.88003s9) + +(my-assert + (- 0.858986s0 1.31028s9) + -1.31028s9) + +(my-assert + (- 0.56377s0 -3.26553s9) + 3.26553s9) + +(my-assert + (- 0.80342s0 -1.46217s9) + 1.46217s9) + +(my-assert + (- 0.093941s0 8.30203s9) + -8.30203s9) + +(my-assert + (- 0.266243s0 4.980s-14) + 0.266243s0) + +(my-assert + (- -0.169983s0 8.01s-15) + -0.169983s0) + +(my-assert + (- 0.77925s0 -2.777s-15) + 0.77925s0) + +(my-assert + (- -0.379807s0 3.990s-15) + -0.379807s0) + +(my-assert + (- -0.392517s0 1.1080s-13) + -0.392517s0) + +(my-assert + (- -0.26274s0 -7.575s-14) + -0.26274s0) + +(my-assert + (- 0.72031s0 4.1223s19) + -4.1223s19) + +(my-assert + (- 0.589775s0 -2.9271s19) + 2.9271s19) + +(my-assert + (- 0.205704s0 -8.4906s19) + 8.4906s19) + +(my-assert + (- 0.362556s0 6.8624s19) + -6.8624s19) + +(my-assert + (- -0.604004s0 -1.42777s19) + 1.42777s19) + +(my-assert + (- -0.53121s0 2.3539s19) + -2.3539s19) + +(my-assert + (- -0.684906s0 8.179s-24) + -0.684906s0) + +(my-assert + (- 0.43084s0 -5.849s-24) + 0.43084s0) + +(my-assert + (- 0.153358s0 3.633s-24) + 0.153358s0) + +(my-assert + (- 0.93678s0 9.13s-24) + 0.93678s0) + +(my-assert + (- 0.78924s0 -7.766s-24) + 0.78924s0) + +(my-assert + (- 0.33867s0 3.510s-24) + 0.33867s0) + +(my-assert + (- 8.0573s9 -0.86206s0) + 8.0573s9) + +(my-assert + (- 9.3318s9 -0.93273s0) + 9.3318s9) + +(my-assert + (- -4.26515s9 0.464104s0) + -4.26515s9) + +(my-assert + (- -3.35557s9 -0.93267s0) + -3.35557s9) + +(my-assert + (- -6.81614s9 -0.64528s0) + -6.81614s9) + +(my-assert + (- -5.099s9 0.67011s0) + -5.099s9) + +(my-assert + (- -4.2206s9 4.9182s9) + -9.1389s9) + +(my-assert + (- -5.18173s9 2.267s9) + -7.4487s9) + +(my-assert + (- 5.53314s9 6.08856s9) + -5.5542s8) + +(my-assert + (- 9.88s9 -3.3333s9) + 1.32132s10) + +(my-assert + (- 4.87404s9 7.17075s9) + -2.2967s9) + +(my-assert + (- -2.9911s9 -1.37177s8) + -2.85393s9) + +(my-assert + (- -8.1379s9 3.023s-15) + -8.1379s9) + +(my-assert + (- 4.8877s9 -1.1596s-13) + 4.8877s9) + +(my-assert + (- -1.89071s9 -4.330s-14) + -1.89071s9) + +(my-assert + (- 8.7563s9 -4.676s-14) + 8.7563s9) + +(my-assert + (- -4.4533s9 2.743s-15) + -4.4533s9) + +(my-assert + (- 4.0261s9 2.1618s-13) + 4.0261s9) + +(my-assert + (- 9.1731s9 -8.0954s19) + 8.0954s19) + +(my-assert + (- 6.984s9 1.09772s19) + -1.09772s19) + +(my-assert + (- -9.8832s9 -8.0905s19) + 8.0905s19) + +(my-assert + (- -8.5769s9 -6.24565s19) + 6.24565s19) + +(my-assert + (- 8.5486s9 2.77396s19) + -2.77396s19) + +(my-assert + (- -9.4026s9 -3.5611s19) + 3.5611s19) + +(my-assert + (- 5.1003s9 -1.9535s-23) + 5.1003s9) + +(my-assert + (- 1.88706s9 -1.6304s-23) + 1.88706s9) + +(my-assert + (- -9.4567s9 -1.9848s-23) + -9.4567s9) + +(my-assert + (- 9.6498s9 -1.57531s-21) + 9.6498s9) + +(my-assert + (- -5.733s9 1.23215s-21) + -5.733s9) + +(my-assert + (- -4.0567s9 -5.229s-24) + -4.0567s9) + +(my-assert + (- -4.379s-14 -0.0201035s0) + 0.0201035s0) + +(my-assert + (- -4.036s-14 0.82034s0) + -0.82034s0) + +(my-assert + (- 1.6661s-13 -0.70753s0) + 0.70753s0) + +(my-assert + (- 3.360s-14 0.60217s0) + -0.60217s0) + +(my-assert + (- 4.977s-14 -0.95905s0) + 0.95905s0) + +(my-assert + (- -2.967s-14 0.55465s0) + -0.55465s0) + +(my-assert + (- 4.394s-14 2.01859s9) + -2.01859s9) + +(my-assert + (- 3.683s-14 4.77836s9) + -4.77836s9) + +(my-assert + (- -6.887s-14 -9.26s9) + 9.26s9) + +(my-assert + (- -2.643s-15 -5.6812s9) + 5.6812s9) + +(my-assert + (- -8.498s-14 -9.3728s9) + 9.3728s9) + +(my-assert + (- 9.033s-14 2.18002s9) + -2.18002s9) + +(my-assert + (- 3.113s-14 -9.207s-14) + 1.232s-13) + +(my-assert + (- -3.239s-15 -1.2957s-13) + 1.26331s-13) + +(my-assert + (- 3.098s-15 -6.117s-15) + 9.2151s-15) + +(my-assert + (- 1.7706s-13 4.829s-14) + 1.2877s-13) + +(my-assert + (- 2.793s-15 8.620s-14) + -8.3407s-14) + +(my-assert + (- -5.019s-14 4.125s-14) + -9.144s-14) + +(my-assert + (- -9.495s-14 -6.06994s18) + 6.06994s18) + +(my-assert + (- 9.385s-14 -7.9288s19) + 7.9288s19) + +(my-assert + (- -3.099s-14 -6.64095s19) + 6.64095s19) + +(my-assert + (- 3.397s-15 2.92222s19) + -2.92222s19) + +(my-assert + (- -8.463s-14 -4.9708s19) + 4.9708s19) + +(my-assert + (- -2.735s-15 -9.2672s19) + 9.2672s19) + +(my-assert + (- -2.974s-14 -7.975s-24) + -2.974s-14) + +(my-assert + (- -2.1853s-13 2.736s-24) + -2.1853s-13) + +(my-assert + (- 3.243s-15 -6.867s-24) + 3.243s-15) + +(my-assert + (- 4.792s-14 -2.659s-24) + 4.792s-14) + +(my-assert + (- 4.672s-14 7.831s-24) + 4.672s-14) + +(my-assert + (- 2.0285s-13 2.741s-24) + 2.0285s-13) + +(my-assert + (- -9.1884s19 -0.22573s0) + -9.1884s19) + +(my-assert + (- 3.32245s19 0.7651s0) + 3.32245s19) + +(my-assert + (- 4.13513s17 0.85135s0) + 4.13513s17) + +(my-assert + (- 2.2249s19 0.45778s0) + 2.2249s19) + +(my-assert + (- 4.9103s19 0.84862s0) + 4.9103s19) + +(my-assert + (- 4.27386s19 -0.06662s0) + 4.27386s19) + +(my-assert + (- -6.725s19 5.11246s8) + -6.725s19) + +(my-assert + (- -2.40906s19 7.2238s9) + -2.40906s19) + +(my-assert + (- 6.1667s19 -7.4303s9) + 6.1667s19) + +(my-assert + (- -7.746s19 -4.29687s8) + -7.746s19) + +(my-assert + (- -1.81419s19 -5.68164s9) + -1.81419s19) + +(my-assert + (- 7.0665s19 -8.9546s8) + 7.0665s19) + +(my-assert + (- 2.47788s19 -2.2961s-13) + 2.47788s19) + +(my-assert + (- -7.4962s19 -3.378s-14) + -7.4962s19) + +(my-assert + (- 1.72135s19 7.168s-14) + 1.72135s19) + +(my-assert + (- 8.3699s19 4.887s-14) + 8.3699s19) + +(my-assert + (- -4.5701s19 -8.009s-14) + -4.5701s19) + +(my-assert + (- -2.845s18 1.1087s-13) + -2.845s18) + +(my-assert + (- 6.4084s19 -4.569s19) + 1.09774s20) + +(my-assert + (- 1.33888s19 -6.8446s19) + 8.1835s19) + +(my-assert + (- -4.0631s19 1.50864s19) + -5.57174s19) + +(my-assert + (- -5.61754s18 2.6413s18) + -8.2588s18) + +(my-assert + (- -9.0749s19 6.21626s19) + -1.5291s20) + +(my-assert + (- -8.5269s19 6.2002s19) + -1.47271s20) + +(my-assert + (- 3.15773s19 5.433s-24) + 3.15773s19) + +(my-assert + (- 5.1563s19 -1.6366s-23) + 5.1563s19) + +(my-assert + (- -5.8449s19 3.282s-24) + -5.8449s19) + +(my-assert + (- 4.70947s19 1.5640s-23) + 4.70947s19) + +(my-assert + (- -4.32334s19 -1.0593s-23) + -4.32334s19) + +(my-assert + (- 7.9621s19 5.610s-24) + 7.9621s19) + +(my-assert + (- 8.164s-24 0.133362s0) + -0.133362s0) + +(my-assert + (- -1.57089s-21 0.3154s0) + -0.3154s0) + +(my-assert + (- -3.736s-24 -0.66536s0) + 0.66536s0) + +(my-assert + (- -6.923s-24 -0.431366s0) + 0.431366s0) + +(my-assert + (- 3.345s-24 0.77436s0) + -0.77436s0) + +(my-assert + (- -1.4322s-23 0.799644s0) + -0.799644s0) + +(my-assert + (- -1.3249s-23 -4.22035s9) + 4.22035s9) + +(my-assert + (- 2.707s-24 -6.5029s9) + 6.5029s9) + +(my-assert + (- -3.490s-24 -2.5205s9) + 2.5205s9) + +(my-assert + (- -1.0086s-23 1.35048s9) + -1.35048s9) + +(my-assert + (- 1.4406s-23 1.55487s9) + -1.55487s9) + +(my-assert + (- 3.370s-24 -4.3973s9) + 4.3973s9) + +(my-assert + (- -1.31249s-21 3.448s-14) + -3.448s-14) + +(my-assert + (- -7.706s-24 -1.9488s-13) + 1.9488s-13) + +(my-assert + (- -9.8403s-22 2.2940s-13) + -2.294s-13) + +(my-assert + (- -3.355s-24 1.0187s-13) + -1.0187s-13) + +(my-assert + (- 9.5635s-22 -8.663s-14) + 8.663s-14) + +(my-assert + (- -5.713s-24 -3.169s-14) + 3.169s-14) + +(my-assert + (- 2.645s-24 -5.2307s19) + 5.2307s19) + +(my-assert + (- -9.960s-24 -9.2854s19) + 9.2854s19) + +(my-assert + (- 8.036s-24 -7.11434s19) + 7.11434s19) + +(my-assert + (- 3.475s-24 -4.845s19) + 4.845s19) + +(my-assert + (- -3.062s-24 4.91714s19) + -4.91714s19) + +(my-assert + (- -2.541s-24 -2.91276s19) + 2.91276s19) + +(my-assert + (- 1.4371s-23 1.1606s-23) + 2.76508s-24) + +(my-assert + (- -1.8769s-23 2.965s-24) + -2.1734s-23) + +(my-assert + (- 3.713s-24 -1.7581s-23) + 2.1294s-23) + +(my-assert + (- -5.954s-24 -2.764s-24) + -3.19s-24) + +(my-assert + (- 3.21502s-22 8.56s-24) + 3.12942s-22) + +(my-assert + (- 9.969s-24 5.912s-24) + 4.057s-24) + +;; ---- Test von * --- + +(my-assert + (* -0.56581s0 -0.117477s0) + 0.06647s0) + +(my-assert + (* 0.73841s0 0.08886s0) + 0.065615s0) + +(my-assert + (* -0.75174s0 -0.173615s0) + 0.130512s0) + +(my-assert + (* 0.557236s0 -0.105034s0) + -0.0585284s0) + +(my-assert + (* -0.62105s0 0.828835s0) + -0.51475s0) + +(my-assert + (* -0.54287s0 -0.92243s0) + 0.50076s0) + +(my-assert + (* -0.2173s0 5.5084s9) + -1.19698s9) + +(my-assert + (* 0.467354s0 -7.9517s9) + -3.71625s9) + +(my-assert + (* -0.95485s0 5.6451s9) + -5.3902s9) + +(my-assert + (* 0.0472946s0 -6.774s9) + -3.20373s8) + +(my-assert + (* 0.196037s0 7.3548s8) + 1.44181s8) + +(my-assert + (* -0.25535s0 4.91907s9) + -1.25608s9) + +(my-assert + (* 0.047058s0 6.612s-14) + 3.11147s-15) + +(my-assert + (* -0.35054s0 3.764s-14) + -1.31943s-14) + +(my-assert + (* 0.372635s0 1.0613s-13) + 3.9548s-14) + +(my-assert + (* 0.627266s0 -9.519s-14) + -5.971s-14) + +(my-assert + (* -0.0293884s0 1.1626s-13) + -3.41667s-15) + +(my-assert + (* -0.88304s0 -1.1160s-13) + 9.8547s-14) + +(my-assert + (* 0.318016s0 -6.86827s19) + -2.18422s19) + +(my-assert + (* 0.605064s0 3.4281s19) + 2.07422s19) + +(my-assert + (* -0.65415s0 -8.185s19) + 5.3542s19) + +(my-assert + (* 0.87548s0 6.72325s19) + 5.8861s19) + +(my-assert + (* 0.45806s0 -9.503s19) + -4.35295s19) + +(my-assert + (* -0.995384s0 1.62797s19) + -1.62045s19) + +(my-assert + (* 0.26301s0 -1.3169s-23) + -3.46357s-24) + +(my-assert + (* 0.82762s0 -3.411s-24) + -2.82304s-24) + +(my-assert + (* -0.042412s0 -3.339s-24) + 1.41613s-25) + +(my-assert + (* 0.858284s0 -7.610s-24) + -6.53157s-24) + +(my-assert + (* 0.75574s0 1.0518s-23) + 7.9488s-24) + +(my-assert + (* 0.977s0 -5.944s-24) + -5.8073s-24) + +(my-assert + (* 1.1316s9 0.87906s0) + 9.9474s8) + +(my-assert + (* 9.7596s9 0.58181s0) + 5.67824s9) + +(my-assert + (* 5.5896s9 -0.91708s0) + -5.12616s9) + +(my-assert + (* -7.677s9 -0.67695s0) + 5.19694s9) + +(my-assert + (* -4.73655s9 0.65572s0) + -3.10588s9) + +(my-assert + (* -3.2158s9 -0.30076s0) + 9.6717s8) + +(my-assert + (* 5.94916s9 -1.02867s9) + -6.1197s18) + +(my-assert + (* -3.19098s9 8.125s9) + -2.59267s19) + +(my-assert + (* -6.57215s9 9.4253s9) + -6.1944s19) + +(my-assert + (* -5.2792s9 3.93547s9) + -2.0776s19) + +(my-assert + (* 2.502s9 4.1275s9) + 1.0327s19) + +(my-assert + (* -8.9462s9 -4.72174s9) + 4.22415s19) + +(my-assert + (* -8.9588s9 -1.4190s-14) + 1.27126s-4) + +(my-assert + (* -3.56218s9 -9.982s-14) + 3.5558s-4) + +(my-assert + (* -3.4449s9 4.582s-15) + -1.57845s-5) + +(my-assert + (* -3.7047s9 1.2985s-14) + -4.8105s-5) + +(my-assert + (* -8.9172s8 -7.294s-14) + 6.5043s-5) + +(my-assert + (* 1.64864s9 1.8344s-13) + 3.02427s-4) + +(my-assert + (* -9.935s8 -7.9116s19) + 7.8602s28) + +(my-assert + (* -7.0441s9 -6.3448s19) + 4.4693s29) + +(my-assert + (* 7.72866s9 1.44264s19) + 1.11497s29) + +(my-assert + (* 3.7816s9 -3.16285s19) + -1.19606s29) + +(my-assert + (* -1.06926s9 6.67816s19) + -7.1407s28) + +(my-assert + (* 4.04482s9 -3.52235s19) + -1.42473s29) + +(my-assert + (* -8.77s8 -3.499s-24) + 3.06864s-15) + +(my-assert + (* -9.5508s9 1.0006s-23) + -9.5566s-14) + +(my-assert + (* -2.98736s9 -7.070s-24) + 2.11207s-14) + +(my-assert + (* 9.9779s9 1.2683s-23) + 1.26548s-13) + +(my-assert + (* 7.4813s9 -1.3730s-23) + -1.02719s-13) + +(my-assert + (* 8.5804s9 6.999s-24) + 6.0054s-14) + +(my-assert + (* 4.637s-14 0.895805s0) + 4.15384s-14) + +(my-assert + (* 1.0125s-13 -0.322685s0) + -3.26718s-14) + +(my-assert + (* 2.310s-16 0.0601425s0) + 1.38928s-17) + +(my-assert + (* 1.0579s-13 -0.27089s0) + -2.86576s-14) + +(my-assert + (* 9.540s-14 -0.21251s0) + -2.02735s-14) + +(my-assert + (* -4.463s-14 -0.96336s0) + 4.2995s-14) + +(my-assert + (* 3.270s-14 -5.9141s9) + -1.93391s-4) + +(my-assert + (* -6.515s-14 1.01791s9) + -6.6318s-5) + +(my-assert + (* 3.695s-14 8.7417s9) + 3.23005s-4) + +(my-assert + (* -1.0900s-13 -6.75794s9) + 7.3662s-4) + +(my-assert + (* 4.551s-14 -7.1112s9) + -3.2363s-4) + +(my-assert + (* 5.456s-15 -5.44014s9) + -2.96813s-5) + +(my-assert + (* -3.377s-14 3.358s-15) + -1.13399s-28) + +(my-assert + (* 3.862s-14 7.278s-14) + 2.81079s-27) + +(my-assert + (* 9.449s-14 3.170s-14) + 2.99533s-27) + +(my-assert + (* 7.051s-14 -4.234s-14) + -2.98537s-27) + +(my-assert + (* -8.955s-14 9.895s-14) + -8.861s-27) + +(my-assert + (* -1.6752s-13 -7.341s-14) + 1.22977s-26) + +(my-assert + (* 9.420s-14 4.50844s19) + 4246900.0s0) + +(my-assert + (* 2.0183s-13 9.598s19) + 1.93715s7) + +(my-assert + (* -7.441s-14 -5.7324s19) + 4265500.0s0) + +(my-assert + (* 7.241s-14 -5.79135s19) + -4193500.0s0) + +(my-assert + (* 7.987s-14 8.1113s19) + 6478500.0s0) + +(my-assert + (* -1.1603s-13 7.4468s19) + -8640500.0s0) + +(my-assert + (* -4.432s-14 -6.851s-24) + 3.03637s-37) + +(my-assert + (* -5.064s-14 -8.119s-24) + 4.1115s-37) + +(my-assert + (* 3.553s-15 -6.404s-24) + -2.27533s-38) + +(my-assert + (* 8.699s-14 -3.558s-24) + -3.0951s-37) + +(my-assert + (* 9.820s-14 -5.771s-24) + -5.6671s-37) + +(my-assert + (* -3.477s-14 7.723s-24) + -2.6853s-37) + +(my-assert + (* 7.9082s19 0.71604s0) + 5.6626s19) + +(my-assert + (* -6.83905s19 -0.36905s0) + 2.52396s19) + +(my-assert + (* -7.7697s19 -0.34073s0) + 2.64736s19) + +(my-assert + (* -2.10557s19 -0.58961s0) + 1.24146s19) + +(my-assert + (* 9.0963s19 -0.37693s0) + -3.42865s19) + +(my-assert + (* -4.24076s19 0.91147s0) + -3.8653s19) + +(my-assert + (* -3.5865s19 -6.4046s9) + 2.297s29) + +(my-assert + (* 7.19225s18 -7.7232s9) + -5.5547s28) + +(my-assert + (* 1.98907s19 -9.9239s9) + -1.97393s29) + +(my-assert + (* -4.27195s19 7.0734s9) + -3.02173s29) + +(my-assert + (* -8.3115s19 5.2947s9) + -4.40073s29) + +(my-assert + (* 9.4386s19 8.6548s8) + 8.169s28) + +(my-assert + (* 6.21677s19 -3.135s-14) + -1948960.0s0) + +(my-assert + (* -6.30774s19 1.5884s-13) + -1.00192s7) + +(my-assert + (* 7.6073s19 3.922s-14) + 2983550.0s0) + +(my-assert + (* -1.44485s19 -3.355s-14) + 484748.0s0) + +(my-assert + (* 3.39653s19 -7.679s-14) + -2608200.0s0) + +(my-assert + (* -6.0072s19 1.7825s-13) + -1.07078s7) + +(my-assert + (* 1.06812s16 -1.19583s19) + -1.2773s35) + +(my-assert + (* 1.1438s19 2.616s-24) + 2.99218s-5) + +(my-assert + (* -5.79304s18 -3.095s-24) + 1.79296s-5) + +(my-assert + (* -7.6387s19 8.607s-24) + -6.5746s-4) + +(my-assert + (* 4.03933s19 3.058s-24) + 1.23523s-4) + +(my-assert + (* -2.06994s19 -1.1381s-23) + 2.3558s-4) + +(my-assert + (* 3.7857s18 -3.590s-24) + -1.35906s-5) + +(my-assert + (* 5.656s-24 -0.096458s0) + -5.4557s-25) + +(my-assert + (* -5.799s-24 -0.148445s0) + 8.6083s-25) + +(my-assert + (* -9.041s-24 0.86431s0) + -7.8143s-24) + +(my-assert + (* -2.645s-24 -0.911865s0) + 2.41187s-24) + +(my-assert + (* -9.758s-24 -0.397186s0) + 3.87574s-24) + +(my-assert + (* -5.345s-24 -0.27215s0) + 1.45463s-24) + +(my-assert + (* -3.713s-24 9.11335s8) + -3.38382s-15) + +(my-assert + (* -3.010s-24 -9.5278s9) + 2.86784s-14) + +(my-assert + (* -1.6904s-23 -8.37655s9) + 1.41599s-13) + +(my-assert + (* -5.074s-24 -9.2804s9) + 4.7089s-14) + +(my-assert + (* -6.942s-22 -8.7038s9) + 6.04217s-12) + +(my-assert + (* -7.643s-24 -3.1665s9) + 2.42018s-14) + +(my-assert + (* -2.659s-24 -9.238s-14) + 2.4564s-37) + +(my-assert + (* -1.7036s-23 3.138s-14) + -5.34586s-37) + +(my-assert + (* 7.684s-24 8.639s-14) + 6.6383s-37) + +(my-assert + (* -3.424s-24 -6.046s-14) + 2.07014s-37) + +(my-assert + (* 9.3102s-22 -1.1344s-13) + -1.05614s-34) + +(my-assert + (* 8.070s-24 3.573s-14) + 2.8834s-37) + +(my-assert + (* 3.557s-24 7.9957s19) + 2.84407s-4) + +(my-assert + (* 7.281s-24 -3.45443s19) + -2.5152s-4) + +(my-assert + (* -1.6093s-23 3.22463s19) + -5.1894s-4) + +(my-assert + (* -1.8628s-23 4.95593s19) + -9.2319s-4) + +(my-assert + (* 3.463s-24 -4.44685s19) + -1.53994s-4) + +(my-assert + (* -8.081s-24 -1.54701s19) + 1.25013s-4) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.403114s0 0.64293s0)) + (-1 0.239813s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.538574s0 0.74157s0)) + (-1 0.202993s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.59919s0 -0.433258s0)) + (-2 -0.26733s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.62148s0 -0.185875s0)) + (3 -0.063861s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.298317s0 -0.79534s0)) + (-1 -0.49703s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.84822s0 9.519s9)) + (0 0.84822s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.185059s0 -4.4452s9)) + (-1 -4.4452s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.442635s0 -4.64486s9)) + (0 -0.442635s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.78401s0 -8.4401s9)) + (-1 -8.4401s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.300156s0 -4.4083s9)) + (-1 -4.4083s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.67763s0 2.54755s9)) + (0 0.67763s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.189995s0 -1.9236s-13)) + (987708260352 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.442696s0 -4.184s-15)) + (-105806519336960 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.175987s0 -5.055s-15)) + (-34814468030464 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.30565s0 -4.296s-14)) + (-7114747543552 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.256264s0 4.541s-14)) + (5643318591488 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.51656s0 4.057s-14)) + (-12732698984448 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.221672s0 -5.9783s19)) + (0 -0.221672s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.441925s0 -8.1227s19)) + (0 -0.441925s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.73287s0 -3.99683s19)) + (-1 -3.99683s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.376198s0 9.1146s19)) + (-1 9.1146s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.61628s0 -5.83824s19)) + (-1 -5.83824s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.072037s0 4.40705s19)) + (-1 4.40705s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.378708s0 3.258s-24)) + (116238699015966918967296 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.98937s0 -7.698s-24)) + (-128524230569057480343552 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.94075s0 -1.0053s-23)) + (93579179764423948500992 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.263123s0 -3.060s-24)) + (-85988344578092468011008 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.58892s0 -1.1106s-23)) + (53027471682887319814144 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.38977s0 -2.812s-24)) + (138609987891358177689600 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.46599s9 0.338676s0)) + (-4328587264 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.326s9 0.91743s0)) + (-6895370240 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.63617s9 -0.569855s0)) + (6380847104 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.45737s9 0.9508s0)) + (-1532788736 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.24714s9 0.45768s0)) + (11464605696 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.1693s9 0.69472s0)) + (11759255552 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.7664s9 -1.9246s9)) + (1 -8.418s8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.29057s9 -7.18694s9)) + (-2 -6.0833s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.7409s9 8.9158s9)) + (0 6.7409s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.4039s9 -1.80932s9)) + (-6 -1.45206s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.4432s9 -7.587s9)) + (-1 -3.14373s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.8365s9 -3.4401s8)) + (14 -2.03249s7)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.70575s9 2.813s-15)) + (1672861433068424397848576 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.37706s8 1.1696s-13)) + (7162308674587923054592 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.9421s9 3.384s-15)) + (1460410281571511491887104 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.4391s8 6.964s-14)) + (13554177553722320617472 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.56217s8 3.380s-14)) + (10538999588799264063488 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.53166s9 7.011s-14)) + (107426919956256787529728 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.3385s9 -7.8903s19)) + (0 -5.3385s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.5786s8 -6.5112s19)) + (0 -5.5786s8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.0502s9 -2.57187s18)) + (0 -7.0502s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.48724s9 3.0864s19)) + (0 3.48724s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.195s9 6.9068s19)) + (-1 6.9068s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.40785s9 6.1696s19)) + (0 6.40785s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.9772s9 -3.455s-24)) + (2887787295482420840947083445796864 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.3337s9 -2.757s-24)) + (-2297319607304237298946798769930240 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.24916s9 8.958s-24)) + (251078998767860827355040375111680 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.695s9 -9.695s-24)) + (484267288087969338977238606938112 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.84457s9 -7.7713s-22)) + (7520717852416051178813723246592 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.01576s9 6.682s-24)) + (-301671132293375748429617783898112 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.7042s-13 -0.80732s0)) + (-1 -0.80732s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.959s-14 0.9918s0)) + (0 4.959s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.0820s-13 0.75837s0)) + (0 2.08202s-13)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.808s-14 0.89121s0)) + (0 4.808s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.005s-14 0.71084s0)) + (-1 0.71084s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.497s-14 -0.83223s0)) + (-1 -0.83223s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.538s-14 3.81524s9)) + (-1 3.81524s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.0888s-13 2.5705s9)) + (-1 2.5705s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.0445s-15 3.9579s9)) + (-1 3.9579s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.399s-14 3.8115s9)) + (-1 3.8115s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.889s-14 1.02951s9)) + (0 8.889s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.408s-14 -5.5562s9)) + (0 -4.40806s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.4679s-13 -1.9105s-13)) + (-1 -4.426s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.2740s-14 -4.935s-14)) + (-1 -3.661s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.321s-14 -8.355s-14)) + (0 -4.32102s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.1228s-13 -3.641s-14)) + (3 -3.0501s-15)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.643s-14 9.809s-14)) + (0 4.643s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.832s-14 1.2918s-13)) + (0 6.832s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.186s-15 7.2502s19)) + (-1 7.2502s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.570s-14 -6.8838s19)) + (-1 -6.8838s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.5446s-14 -8.6798s19)) + (0 -1.5446s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.2496s-13 -8.0029s19)) + (0 -1.24963s-13)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.303s-15 -9.7969s19)) + (0 -3.303s-15)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.832s-14 5.17976s19)) + (-1 5.17976s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.1039s-13 1.1031s-23)) + (-10007216128 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.303s-14 -1.61171s-21)) + (20493824 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.660s-14 -1.3664s-23)) + (-2678554624 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.9574s-13 -6.864s-24)) + (28516810752 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.285s-14 -3.329s-24)) + (-9867755520 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.291s-15 4.2038s-23)) + (-78285824 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.18707s19 0.231445s0)) + (-310527697906823069696 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.5173s19 -0.0566254s0)) + (-1680761395333178589184 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.6524s19 -0.697136s0)) + (95424520704539754496 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.42423s19 0.68306s0)) + (50130693352167833600 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.2388s19 0.0522995s0)) + (-1384100280679029276672 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.9235s18 -0.24643s0)) + (-24037400061136601088 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.63137s18 -1.6819s9)) + (1564524544 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.4749s19 -2.36457s9)) + (-10466623488 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.07847s19 6.4981s9)) + (-3198582784 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.54907s19 4.4446s9)) + (-5735186432 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.34573s19 3.0757s9)) + (7626620928 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.93055s19 4.8192s9)) + (-4005953536 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.4928s19 9.588s-14)) + (468585063670302141654816501268480 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.17698s19 -3.259s-14)) + (667992445198391196335567431270400 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.3605s19 -1.2702s-13)) + (658197863607565267600565560410112 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.2775s19 3.555s-15)) + (14845297722947765992252704150257664 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.0371s19 6.922s-15)) + (-7276948270610150879291824750460928 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.3107s18 -1.0201s-13)) + (-81468833985370875891111365181440 0.0s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.8796s19 3.8685s19)) + (-2 3.85733s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.11224s18 -7.757s19)) + (-1 -7.34577s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.7228s19 -6.0107s19)) + (0 -1.72278s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.1191s19 -4.49645s19)) + (-3 -4.3702s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.2755s19 8.9417s19)) + (0 4.2755s19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.3237s19 -1.9687s19)) + (2 -3.86314s18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.109s-24 0.00614166s0)) + (0 3.109s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.2027s-23 0.0328217s0)) + (-1 0.0328217s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.017s-24 0.76966s0)) + (-1 0.76966s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.628s-24 0.47249s0)) + (-1 0.47249s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.323s-24 -0.86671s0)) + (-1 -0.86671s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.302s-24 0.0245514s0)) + (-1 0.0245514s0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.342s-24 6.0717s9)) + (0 5.34194s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.664s-24 5.573s9)) + (-1 5.573s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.830s-24 7.0363s9)) + (-1 7.0363s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.176s-24 1.12686s9)) + (-1 1.12686s9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.2026s-22 -3.99255s9)) + (0 -2.2026s-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.994s-24 5.81167s9)) + (0 6.994s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.054s-24 -8.915s-14)) + (-1 -8.915s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.875s-24 3.652s-14)) + (0 2.875s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.57853s-22 -4.501s-14)) + (0 -1.57853s-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.3880s-23 -1.0479s-13)) + (0 -1.388s-23)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.879s-24 3.974s-14)) + (-1 3.974s-14)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.14395s-21 -4.527s-14)) + (0 -1.14395s-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.149s-24 9.418s-24)) + (0 6.149s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.661s-24 -2.956s-24)) + (-3 -1.20701s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.254s-24 1.2764s-22)) + (0 3.254s-24)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.4542s-22 5.574s-24)) + (-98 8.2738s-25)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.4523s-23 3.091s-24)) + (-5 9.3198s-25)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.913s-24 8.419s-24)) + (-1 2.506s-24)) + +;; ---- Test von / --- + +(my-assert + (/ 0.4319s0 0.279747s0) + 1.5439s0) + +(my-assert + (/ 0.58111s0 0.474937s0) + 1.22354s0) + +(my-assert + (/ 0.95817s0 -0.209396s0) + -4.57587s0) + +(my-assert + (/ -0.30497s0 -0.182861s0) + 1.66777s0) + +(my-assert + (/ -0.69316s0 -0.32908s0) + 2.10635s0) + +(my-assert + (/ -0.87152s0 0.518326s0) + -1.68141s0) + +(my-assert + (/ -0.81208s0 3.27736s9) + -2.47784s-10) + +(my-assert + (/ 0.88465s0 2.15492s9) + 4.10527s-10) + +(my-assert + (/ -0.96446s0 8.0971s9) + -1.19112s-10) + +(my-assert + (/ -0.65258s0 -3.98033s9) + 1.6395s-10) + +(my-assert + (/ 0.663826s0 -7.88726s8) + -8.41645s-10) + +(my-assert + (/ -0.31185s0 4.1015s9) + -7.6033s-11) + +(my-assert + (/ -0.89607s0 -3.887s-14) + 2.3053s13) + +(my-assert + (/ -0.670135s0 -5.027s-14) + 1.33306s13) + +(my-assert + (/ 0.94663s0 -6.153s-14) + -1.5385s13) + +(my-assert + (/ -0.76772s0 4.033s-14) + -1.90358s13) + +(my-assert + (/ -0.446358s0 -1.9017s-13) + 2.34713s12) + +(my-assert + (/ -0.157814s0 -2.0401s-13) + 7.73555s11) + +(my-assert + (/ 0.636185s0 -3.78516s19) + -1.68073s-20) + +(my-assert + (/ -0.90556s0 7.7192s19) + -1.17314s-20) + +(my-assert + (/ 0.85053s0 8.3134s19) + 1.02309s-20) + +(my-assert + (/ -0.3058s0 3.00674s19) + -1.01705s-20) + +(my-assert + (/ 0.219429s0 -8.1184s19) + -2.70286s-21) + +(my-assert + (/ 0.319603s0 -2.0739s19) + -1.54106s-20) + +(my-assert + (/ 0.58943s0 -5.280s-24) + -1.11635s23) + +(my-assert + (/ 0.72955s0 7.852s-24) + 9.2914s22) + +(my-assert + (/ -0.66327s0 -3.124s-24) + 2.12315s23) + +(my-assert + (/ -0.0137558s0 -7.918s-24) + 1.73729s21) + +(my-assert + (/ 0.35823s0 5.467s-24) + 6.55263s22) + +(my-assert + (/ 0.93861s0 9.968s-24) + 9.4163s22) + +(my-assert + (/ 3.83346s9 0.99782s0) + 3.84185s9) + +(my-assert + (/ 8.7033s9 -0.81822s0) + -1.06369s10) + +(my-assert + (/ 3.52326s8 -0.79994s0) + -4.4044s8) + +(my-assert + (/ 8.0525s9 -0.91803s0) + -8.7715s9) + +(my-assert + (/ -2.12784s9 -0.761246s0) + 2.7952s9) + +(my-assert + (/ 1.18805s9 -0.903534s0) + -1.3149s9) + +(my-assert + (/ -6.50556s9 -5.4642s9) + 1.19058s0) + +(my-assert + (/ 3.3333s8 1.8341s8) + 1.81738s0) + +(my-assert + (/ 3.70934s9 9.1957s8) + 4.03375s0) + +(my-assert + (/ -8.0459s9 4.5511s9) + -1.76791s0) + +(my-assert + (/ 3.54982s9 4.6631s8) + 7.6126s0) + +(my-assert + (/ -6.27016s9 -3.42858s9) + 1.8288s0) + +(my-assert + (/ -4.3213s9 7.223s-15) + -5.98274s23) + +(my-assert + (/ -2.57753s9 -2.533s-15) + 1.01759s24) + +(my-assert + (/ 3.8858s9 -4.505s-14) + -8.6256s22) + +(my-assert + (/ 3.5946s9 -5.067s-14) + -7.0941s22) + +(my-assert + (/ 2.94434s9 8.333s-14) + 3.53333s22) + +(my-assert + (/ 5.6178s9 -8.241s-14) + -6.81694s22) + +(my-assert + (/ 4.9591s8 3.9972s19) + 1.24064s-11) + +(my-assert + (/ 2.4166s9 -9.2141s19) + -2.62272s-11) + +(my-assert + (/ -1.484s9 2.0281s19) + -7.3172s-11) + +(my-assert + (/ 2.2339s8 1.96374s19) + 1.13758s-11) + +(my-assert + (/ -6.6306s9 -2.414s19) + 2.7467s-10) + +(my-assert + (/ 9.9114s9 9.6187s19) + 1.03043s-10) + +(my-assert + (/ 4.4579s9 5.343s-24) + 8.3434s32) + +(my-assert + (/ -6.35994s9 -6.301s-24) + 1.00936s33) + +(my-assert + (/ 5.49677s9 -1.9306s-25) + -2.84717s34) + +(my-assert + (/ -5.007s9 3.692s-24) + -1.35617s33) + +(my-assert + (/ 8.6837s9 -1.6358s-23) + -5.3085s32) + +(my-assert + (/ 5.5898s9 -5.435s-24) + -1.02849s33) + +(my-assert + (/ -5.042s-14 0.79081s0) + -6.3758s-14) + +(my-assert + (/ -6.231s-14 0.96946s0) + -6.4273s-14) + +(my-assert + (/ 6.016s-14 0.418983s0) + 1.43587s-13) + +(my-assert + (/ -1.1682s-13 0.70944s0) + -1.64663s-13) + +(my-assert + (/ -1.7485s-13 0.83207s0) + -2.1014s-13) + +(my-assert + (/ 7.831s-15 -0.083374s0) + -9.3926s-14) + +(my-assert + (/ 3.947s-14 9.2342s9) + 4.2744s-24) + +(my-assert + (/ -1.1537s-13 -6.44075s9) + 1.79124s-23) + +(my-assert + (/ 6.751s-14 5.8395s8) + 1.1561s-22) + +(my-assert + (/ -5.026s-14 7.9677s9) + -6.308s-24) + +(my-assert + (/ -1.0105s-13 -1.71082s9) + 5.9066s-23) + +(my-assert + (/ -4.996s-14 9.426s9) + -5.30024s-24) + +(my-assert + (/ -6.837s-14 -3.573s-14) + 1.91351s0) + +(my-assert + (/ -7.736s-14 -4.898s-14) + 1.57942s0) + +(my-assert + (/ 3.777s-14 8.025s-14) + 0.470657s0) + +(my-assert + (/ -6.239s-14 8.518s-15) + -7.32446s0) + +(my-assert + (/ -7.548s-15 -4.573s-14) + 0.165056s0) + +(my-assert + (/ 1.6293s-14 4.712s-14) + 0.345776s0) + +(my-assert + (/ -4.47s-14 2.73658s19) + -1.63342s-33) + +(my-assert + (/ 1.0583s-13 2.52534s19) + 4.19073s-33) + +(my-assert + (/ 4.351s-15 2.70326s19) + 1.60955s-34) + +(my-assert + (/ 3.699s-14 -6.00707s19) + -6.1577s-34) + +(my-assert + (/ 6.358s-14 5.18274s19) + 1.22677s-33) + +(my-assert + (/ -2.971s-14 6.153s19) + -4.8286s-34) + +(my-assert + (/ -4.968s-14 7.699s-24) + -6.4528s9) + +(my-assert + (/ -3.654s-14 8.434s-24) + -4.3325s9) + +(my-assert + (/ -9.276s-14 -7.079s-24) + 1.31035s10) + +(my-assert + (/ -4.556s-14 1.3900s-23) + -3.27772s9) + +(my-assert + (/ 3.832s-14 1.55715s-22) + 2.4609s8) + +(my-assert + (/ 1.4186s-13 1.64482s-21) + 8.6246s7) + +(my-assert + (/ -7.0974s19 -0.705536s0) + 1.00596s20) + +(my-assert + (/ -7.687s19 -0.241531s0) + 3.1826s20) + +(my-assert + (/ 3.37013s19 -0.425987s0) + -7.9114s19) + +(my-assert + (/ 6.56473s19 -0.60696s0) + -1.08158s20) + +(my-assert + (/ 4.1598s19 0.60135s0) + 6.9175s19) + +(my-assert + (/ 8.8312s19 0.93547s0) + 9.4404s19) + +(my-assert + (/ 2.81357s19 -2.62832s9) + -1.07048s10) + +(my-assert + (/ 5.9243s19 -4.5189s8) + -1.311s11) + +(my-assert + (/ -8.3887s19 9.5761s9) + -8.7601s9) + +(my-assert + (/ 7.7606s19 -8.5369s9) + -9.0906s9) + +(my-assert + (/ -7.9868s19 5.0173s9) + -1.59186s10) + +(my-assert + (/ 7.4128s19 -6.7781s9) + -1.09364s10) + +(my-assert + (/ 1.27472s19 1.1699s-13) + 1.0896s32) + +(my-assert + (/ 2.97578s19 4.448s-14) + 6.6901s32) + +(my-assert + (/ 7.19416s19 1.3834s-13) + 5.20034s32) + +(my-assert + (/ 6.61843s19 -4.268s-14) + -1.55071s33) + +(my-assert + (/ 2.8579s19 4.364s-14) + 6.5488s32) + +(my-assert + (/ 8.2451s18 -6.532s-14) + -1.26227s32) + +(my-assert + (/ 4.63364s19 9.4305s19) + 0.491344s0) + +(my-assert + (/ -1.81999s19 1.05424s19) + -1.72636s0) + +(my-assert + (/ -1.41579s19 -4.03517s19) + 0.350864s0) + +(my-assert + (/ -1.88523s18 -3.3165s18) + 0.568436s0) + +(my-assert + (/ 8.4152s17 -7.3293s19) + -0.0114815s0) + +(my-assert + (/ -8.674s19 -3.63595s19) + 2.38562s0) + +(my-assert + (/ -1.64643s-22 0.78035s0) + -2.10986s-22) + +(my-assert + (/ -7.455s-24 -0.63174s0) + 1.18009s-23) + +(my-assert + (/ -3.259s-24 -0.89363s0) + 3.64694s-24) + +(my-assert + (/ 1.5803s-23 -0.11338s0) + -1.39382s-22) + +(my-assert + (/ -3.534s-24 0.407562s0) + -8.6711s-24) + +(my-assert + (/ -7.221s-24 0.90274s0) + -7.999s-24) + +(my-assert + (/ 1.0479s-23 5.66256s8) + 1.85059s-32) + +(my-assert + (/ 1.62856s-21 -1.9551s9) + -8.3298s-31) + +(my-assert + (/ -8.102s-24 9.7896s9) + -8.2761s-34) + +(my-assert + (/ 9.693s-24 -8.777s9) + -1.10437s-33) + +(my-assert + (/ 8.643s-24 -1.25557s9) + -6.8837s-33) + +(my-assert + (/ 3.224s-24 9.8161s9) + 3.2844s-34) + +(my-assert + (/ 1.06582s-21 -1.0408s-13) + -1.02405s-8) + +(my-assert + (/ 1.6738s-23 9.851s-14) + 1.69914s-10) + +(my-assert + (/ -1.1514s-23 -6.509s-14) + 1.76893s-10) + +(my-assert + (/ 9.171s-24 9.292s-14) + 9.8698s-11) + +(my-assert + (/ 1.8589s-23 -4.213s-14) + -4.4123s-10) + +(my-assert + (/ 1.2837s-23 1.1034s-13) + 1.16341s-10) + +(my-assert + (/ 3.671s-24 1.0091s-23) + 0.363792s0) + +(my-assert + (/ -3.373s-24 -1.7017s-23) + 0.198214s0) + +(my-assert + (/ -2.0157s-23 1.0021s-23) + -2.01147s0) + +(my-assert + (/ 8.041s-24 -1.3974s-23) + -0.575424s0) + +(my-assert + (/ -5.391s-24 1.1762s-23) + -0.458344s0) + +(my-assert + (/ 1.7735s-23 -3.313s-24) + -5.3531s0) + +;; ==== S I N G L E - F L O A T S ==== + +;; ---- Test von + --- + +(my-assert + (+ 0.79351956 0.07393837) + 0.8674579) + +(my-assert + (+ -0.52145976 -0.14409256) + -0.6655523) + +(my-assert + (+ -0.094845235 -0.091273725) + -0.18611896) + +(my-assert + (+ -0.11106694 -0.90595967) + -1.0170267) + +(my-assert + (+ 0.46902913 0.6453068) + 1.114336) + +(my-assert + (+ -0.30989015 0.6634996) + 0.35360944) + +(my-assert + (+ -0.58887166 -3.1150198E9) + -3.1150198E9) + +(my-assert + (+ 0.08032262 -8.451643E9) + -8.451643E9) + +(my-assert + (+ -0.734433 7.601292E9) + 7.601292E9) + +(my-assert + (+ 0.77958024 -4.2334996E9) + -4.2334996E9) + +(my-assert + (+ -0.5492505 4.4427484E9) + 4.4427484E9) + +(my-assert + (+ -0.45681345 4.7386803E9) + 4.7386803E9) + +(my-assert + (+ -0.5951412 7.866326E-11) + -0.5951412) + +(my-assert + (+ 0.8511461 8.396644E-11) + 0.8511461) + +(my-assert + (+ -0.94777477 -7.635105E-11) + -0.94777477) + +(my-assert + (+ -0.20783025 -1.7222382E-11) + -0.20783025) + +(my-assert + (+ 0.82520634 -5.3449255E-11) + 0.82520634) + +(my-assert + (+ 0.7797032 3.7409843E-11) + 0.7797032) + +(my-assert + (+ 0.9915549 5.16192E19) + 5.16192E19) + +(my-assert + (+ -0.6311349 2.1599532E19) + 2.1599532E19) + +(my-assert + (+ 0.42801672 4.8533796E18) + 4.8533796E18) + +(my-assert + (+ -0.11165339 6.518633E19) + 6.518633E19) + +(my-assert + (+ -0.5133993 -5.5200484E19) + -5.5200484E19) + +(my-assert + (+ 0.11643493 -1.0541451E19) + -1.0541451E19) + +(my-assert + (+ -0.7063649 8.243067E-21) + -0.7063649) + +(my-assert + (+ 8.4728E-4 -7.5151976E-21) + 8.4728E-4) + +(my-assert + (+ -0.47157037 -8.748518E-21) + -0.47157037) + +(my-assert + (+ 0.7662331 -5.6591384E-21) + 0.7662331) + +(my-assert + (+ -0.9418909 -4.455382E-21) + -0.9418909) + +(my-assert + (+ -0.88412094 6.6664897E-21) + -0.88412094) + +(my-assert + (+ 5.5891533E9 -0.11624104) + 5.5891533E9) + +(my-assert + (+ -8.760519E9 0.22073412) + -8.760519E9) + +(my-assert + (+ 6.8390047E9 -0.6434584) + 6.8390047E9) + +(my-assert + (+ 5.1620844E9 -0.93939686) + 5.1620844E9) + +(my-assert + (+ 9.21372E9 -0.93054956) + 9.21372E9) + +(my-assert + (+ -2.7403366E9 -0.9354063) + -2.7403366E9) + +(my-assert + (+ 6.4755876E9 7.780013E9) + 1.4255601E10) + +(my-assert + (+ 3.6402857E9 -4.6589404E9) + -1.0186547E9) + +(my-assert + (+ 9.858497E9 -3.1216233E9) + 6.7368735E9) + +(my-assert + (+ -5.199144E9 -8.3410964E9) + -1.354024E10) + +(my-assert + (+ -2.2145843E9 7.4088115E9) + 5.194227E9) + +(my-assert + (+ 3.6034734E9 -4.7355105E9) + -1.1320371E9) + +(my-assert + (+ -3.974853E9 8.344858E-11) + -3.974853E9) + +(my-assert + (+ 9.633741E9 9.879035E-11) + 9.633741E9) + +(my-assert + (+ -5.84563E9 -2.8054357E-11) + -5.84563E9) + +(my-assert + (+ 1.6814709E8 -6.702281E-11) + 1.6814709E8) + +(my-assert + (+ 6.627381E8 8.1083654E-11) + 6.627381E8) + +(my-assert + (+ 6.617609E9 -7.74835E-11) + 6.617609E9) + +(my-assert + (+ -4.325255E9 7.48992E19) + 7.48992E19) + +(my-assert + (+ 8.963769E9 5.6527995E19) + 5.6527995E19) + +(my-assert + (+ 3.2307428E9 -3.772047E19) + -3.772047E19) + +(my-assert + (+ -1.5719092E9 9.119215E19) + 9.119215E19) + +(my-assert + (+ -3.1338138E9 2.7048826E19) + 2.7048826E19) + +(my-assert + (+ -4.4506363E9 9.624759E19) + 9.624759E19) + +(my-assert + (+ 1.8499094E9 4.968932E-21) + 1.8499094E9) + +(my-assert + (+ 1.1302281E9 1.590079E-21) + 1.1302281E9) + +(my-assert + (+ 5.7261727E9 -3.3212954E-21) + 5.7261727E9) + +(my-assert + (+ 1.8314988E9 -6.247946E-21) + 1.8314988E9) + +(my-assert + (+ -7.301286E9 -8.870309E-21) + -7.301286E9) + +(my-assert + (+ 8.0970737E9 -6.944993E-21) + 8.0970737E9) + +(my-assert + (+ 9.076142E-11 0.79629874) + 0.79629874) + +(my-assert + (+ -2.5569331E-11 -0.11109424) + -0.11109424) + +(my-assert + (+ 5.817238E-11 0.8669617) + 0.8669617) + +(my-assert + (+ 5.0001194E-11 0.1629681) + 0.1629681) + +(my-assert + (+ -5.314657E-11 0.33499128) + 0.33499128) + +(my-assert + (+ 3.4244614E-11 0.7846571) + 0.7846571) + +(my-assert + (+ 5.016508E-11 1.2850774E9) + 1.2850774E9) + +(my-assert + (+ -6.236206E-11 -3.9463657E9) + -3.9463657E9) + +(my-assert + (+ -9.461717E-11 -2.86016E9) + -2.86016E9) + +(my-assert + (+ 9.271425E-11 9.936099E9) + 9.936099E9) + +(my-assert + (+ -9.330213E-12 4.2810826E9) + 4.2810826E9) + +(my-assert + (+ 8.8110796E-11 -7.967343E9) + -7.967343E9) + +(my-assert + (+ -3.252064E-11 9.310712E-11) + 6.058648E-11) + +(my-assert + (+ 9.2616026E-11 -4.2321837E-11) + 5.029419E-11) + +(my-assert + (+ -6.138445E-11 2.0083374E-11) + -4.130108E-11) + +(my-assert + (+ -1.672895E-11 -4.1673078E-11) + -5.8402026E-11) + +(my-assert + (+ -5.054619E-11 -1.9569606E-11) + -7.0115795E-11) + +(my-assert + (+ -6.765585E-11 6.200571E-11) + -5.65014E-12) + +(my-assert + (+ -8.958499E-11 9.627367E18) + 9.627367E18) + +(my-assert + (+ -3.639458E-11 -6.774422E19) + -6.774422E19) + +(my-assert + (+ 5.885664E-11 7.710968E19) + 7.710968E19) + +(my-assert + (+ -2.8348934E-11 -6.8805507E19) + -6.8805507E19) + +(my-assert + (+ 3.783013E-11 -4.363011E19) + -4.363011E19) + +(my-assert + (+ 9.9192224E-11 7.840148E19) + 7.840148E19) + +(my-assert + (+ 1.5157771E-11 -6.578477E-21) + 1.5157771E-11) + +(my-assert + (+ 3.269849E-11 -1.5641468E-21) + 3.269849E-11) + +(my-assert + (+ -2.4697334E-11 -5.9471063E-21) + -2.4697334E-11) + +(my-assert + (+ -7.226034E-11 -8.027814E-21) + -7.226034E-11) + +(my-assert + (+ 6.705153E-12 1.3146739E-21) + 6.705153E-12) + +(my-assert + (+ -9.281199E-11 1.940757E-22) + -9.281199E-11) + +(my-assert + (+ 6.841885E19 0.29873258) + 6.841885E19) + +(my-assert + (+ -7.487633E19 -0.41199452) + -7.487633E19) + +(my-assert + (+ 9.324847E19 -0.12986994) + 9.324847E19) + +(my-assert + (+ 1.7454827E19 -0.9480438) + 1.7454827E19) + +(my-assert + (+ -2.2794772E19 -0.85242146) + -2.2794772E19) + +(my-assert + (+ -1.4789046E18 -0.3244334) + -1.4789046E18) + +(my-assert + (+ -1.0913384E19 6.2691034E8) + -1.0913384E19) + +(my-assert + (+ 9.054158E19 6.7361736E9) + 9.054158E19) + +(my-assert + (+ -2.404365E19 2.819194E9) + -2.404365E19) + +(my-assert + (+ 3.0628145E19 3.8188636E9) + 3.0628145E19) + +(my-assert + (+ -3.7020847E19 -4.248917E8) + -3.7020847E19) + +(my-assert + (+ 8.556466E19 -5.431256E9) + 8.556466E19) + +(my-assert + (+ 4.8590555E19 -4.0259546E-11) + 4.8590555E19) + +(my-assert + (+ -1.990289E19 -3.2150872E-11) + -1.990289E19) + +(my-assert + (+ -1.5843934E19 5.37822E-11) + -1.5843934E19) + +(my-assert + (+ 1.596058E19 2.465645E-11) + 1.596058E19) + +(my-assert + (+ 8.179266E19 -8.080585E-11) + 8.179266E19) + +(my-assert + (+ 8.673572E19 -2.1405459E-11) + 8.673572E19) + +(my-assert + (+ -4.5302206E19 4.4819714E19) + -4.824921E17) + +(my-assert + (+ 2.1413618E19 -7.160984E19) + -5.0196224E19) + +(my-assert + (+ 9.760235E19 -7.810464E19) + 1.949771E19) + +(my-assert + (+ -7.518544E19 -5.7398474E19) + -1.32583915E20) + +(my-assert + (+ -2.459352E19 6.0089863E19) + 3.5496343E19) + +(my-assert + (+ -9.009707E19 1.9710512E19) + -7.0386556E19) + +(my-assert + (+ 4.9167807E19 -1.261897E-21) + 4.9167807E19) + +(my-assert + (+ -8.647001E18 -1.4144885E-21) + -8.647001E18) + +(my-assert + (+ -6.2763383E19 6.69688E-21) + -6.2763383E19) + +(my-assert + (+ 1.6851938E19 -4.9109547E-21) + 1.6851938E19) + +(my-assert + (+ -7.0371058E19 -9.246501E-21) + -7.0371058E19) + +(my-assert + (+ -2.8498996E19 3.3614294E-21) + -2.8498996E19) + +(my-assert + (+ -4.8211753E-21 0.5153807) + 0.5153807) + +(my-assert + (+ -9.730312E-21 0.3705088) + 0.3705088) + +(my-assert + (+ -8.83036E-21 0.21063423) + 0.21063423) + +(my-assert + (+ 1.8688595E-21 -0.38304192) + -0.38304192) + +(my-assert + (+ -7.9137435E-21 -0.9482965) + -0.9482965) + +(my-assert + (+ -5.7913193E-21 -0.16538233) + -0.16538233) + +(my-assert + (+ -4.667948E-21 5.69782E9) + 5.69782E9) + +(my-assert + (+ -1.6254025E-21 1.100067E9) + 1.100067E9) + +(my-assert + (+ 5.4919865E-21 9.125866E9) + 9.125866E9) + +(my-assert + (+ 2.1973532E-21 -5.218964E9) + -5.218964E9) + +(my-assert + (+ -4.018586E-21 -6.5943096E9) + -6.5943096E9) + +(my-assert + (+ -7.7845274E-22 4.172669E9) + 4.172669E9) + +(my-assert + (+ -2.843846E-21 9.243441E-12) + 9.243441E-12) + +(my-assert + (+ 1.1533075E-21 3.327943E-11) + 3.327943E-11) + +(my-assert + (+ 5.977113E-21 6.507544E-11) + 6.507544E-11) + +(my-assert + (+ 1.1817801E-21 -4.1877824E-11) + -4.1877824E-11) + +(my-assert + (+ 1.932947E-21 9.4013144E-11) + 9.4013144E-11) + +(my-assert + (+ 8.526454E-21 8.396772E-11) + 8.396772E-11) + +(my-assert + (+ -4.8870485E-21 5.9277504E19) + 5.9277504E19) + +(my-assert + (+ -4.7174987E-21 2.5545484E19) + 2.5545484E19) + +(my-assert + (+ -8.818029E-21 1.2602901E19) + 1.2602901E19) + +(my-assert + (+ -1.2268113E-21 -9.071741E19) + -9.071741E19) + +(my-assert + (+ -7.0568975E-21 -6.9825405E19) + -6.9825405E19) + +(my-assert + (+ 8.723312E-21 -5.802767E19) + -5.802767E19) + +(my-assert + (+ 7.1661314E-21 4.10364E-21) + 1.1269772E-20) + +(my-assert + (+ 8.181265E-21 -4.6898657E-21) + 3.4913997E-21) + +(my-assert + (+ -8.570217E-21 -5.5145446E-21) + -1.4084761E-20) + +(my-assert + (+ 1.3507604E-23 -7.152723E-21) + -7.139215E-21) + +(my-assert + (+ -7.859527E-21 -9.369602E-21) + -1.7229128E-20) + +(my-assert + (+ -4.9014434E-21 1.4580911E-21) + -3.443352E-21) + +;; ---- Test von - --- + +(my-assert + (- -0.41894162 0.23777992) + -0.65672153) + +(my-assert + (- 0.74937063 0.4803756) + 0.26899505) + +(my-assert + (- 0.46964037 -0.94880456) + 1.4184449) + +(my-assert + (- 0.16453332 0.035123527) + 0.12940979) + +(my-assert + (- 0.7353321 -0.3952883) + 1.1306204) + +(my-assert + (- -0.33693552 -0.6941588) + 0.35722327) + +(my-assert + (- -0.61853 -9.25498E9) + 9.25498E9) + +(my-assert + (- 0.5172653 -6.728693E9) + 6.728693E9) + +(my-assert + (- 0.1268478 -1.8808037E9) + 1.8808037E9) + +(my-assert + (- 0.29479754 -3.4643973E9) + 3.4643973E9) + +(my-assert + (- 0.34332883 1.4258218E9) + -1.4258218E9) + +(my-assert + (- -0.4093976 -1.6698813E9) + 1.6698813E9) + +(my-assert + (- 0.10942185 -2.015636E-11) + 0.10942185) + +(my-assert + (- 0.30351585 4.4276416E-11) + 0.30351585) + +(my-assert + (- -0.41279083 6.5274E-11) + -0.41279083) + +(my-assert + (- 0.7813598 -5.028443E-11) + 0.7813598) + +(my-assert + (- -0.72214615 2.5959075E-11) + -0.72214615) + +(my-assert + (- -0.8924311 -5.2076333E-11) + -0.8924311) + +(my-assert + (- -0.26128495 6.8887236E19) + -6.8887236E19) + +(my-assert + (- 0.906616 -2.0519019E18) + 2.0519019E18) + +(my-assert + (- 0.96452767 -1.6347343E19) + 1.6347343E19) + +(my-assert + (- -0.99801517 8.383864E19) + -8.383864E19) + +(my-assert + (- -0.60573876 -4.890489E19) + 4.890489E19) + +(my-assert + (- -0.004701972 6.3981E18) + -6.3981E18) + +(my-assert + (- 0.34311903 3.52871E-21) + 0.34311903) + +(my-assert + (- -0.38159567 -2.3400748E-21) + -0.38159567) + +(my-assert + (- -0.6719565 -5.4333447E-21) + -0.6719565) + +(my-assert + (- -0.21363729 8.021308E-21) + -0.21363729) + +(my-assert + (- 0.5275244 -4.88554E-21) + 0.5275244) + +(my-assert + (- 0.9064559 -6.5840867E-21) + 0.9064559) + +(my-assert + (- -3.0312538E8 0.26249015) + -3.0312538E8) + +(my-assert + (- -9.217122E9 0.22172129) + -9.217122E9) + +(my-assert + (- -1.157806E9 -0.95704305) + -1.157806E9) + +(my-assert + (- 6.743087E9 -0.37863714) + 6.743087E9) + +(my-assert + (- -4.0819942E8 -0.068549395) + -4.0819942E8) + +(my-assert + (- 4.586502E9 0.29215187) + 4.586502E9) + +(my-assert + (- 5.091125E9 -2.971223E9) + 8.0623483E9) + +(my-assert + (- -2.1147072E8 -8.537374E9) + 8.3259034E9) + +(my-assert + (- -9.075735E9 -9.072693E9) + -3041280.0) + +(my-assert + (- 1.4614451E9 3.0213921E9) + -1.559947E9) + +(my-assert + (- 8.960645E9 5.4822825E9) + 3.4783626E9) + +(my-assert + (- -3.7246787E9 -2.823592E9) + -9.010867E8) + +(my-assert + (- -3.4256804E9 -1.8245674E-11) + -3.4256804E9) + +(my-assert + (- 7.0777057E9 3.6826153E-11) + 7.0777057E9) + +(my-assert + (- 3.4600579E9 -5.207135E-11) + 3.4600579E9) + +(my-assert + (- 9.57872E9 8.222393E-11) + 9.57872E9) + +(my-assert + (- 8.388926E9 -1.1216945E-11) + 8.388926E9) + +(my-assert + (- 3.8273395E8 1.153788E-11) + 3.8273395E8) + +(my-assert + (- -1.2011469E8 -9.879852E19) + 9.879852E19) + +(my-assert + (- 3.850388E9 4.8155957E19) + -4.8155957E19) + +(my-assert + (- 5.5329756E9 -5.067925E19) + 5.067925E19) + +(my-assert + (- 3.3222902E9 5.2892763E19) + -5.2892763E19) + +(my-assert + (- 4.431185E9 -8.005187E19) + 8.005187E19) + +(my-assert + (- -7.307553E8 -6.8217897E19) + 6.8217897E19) + +(my-assert + (- 7.9813893E9 9.68989E-21) + 7.9813893E9) + +(my-assert + (- -5.7208223E9 9.790913E-21) + -5.7208223E9) + +(my-assert + (- -5.9564112E7 9.217466E-21) + -5.9564112E7) + +(my-assert + (- 5.4524237E9 4.947411E-21) + 5.4524237E9) + +(my-assert + (- 1.4269632E9 -5.1552662E-21) + 1.4269632E9) + +(my-assert + (- 3.7555832E9 -4.168443E-21) + 3.7555832E9) + +(my-assert + (- -4.1575327E-11 -0.38582206) + 0.38582206) + +(my-assert + (- -5.810516E-11 -0.5456566) + 0.5456566) + +(my-assert + (- -1.2386638E-11 -0.6209788) + 0.6209788) + +(my-assert + (- 2.0245033E-11 -0.7418727) + 0.7418727) + +(my-assert + (- 3.7671637E-11 0.1772576) + -0.1772576) + +(my-assert + (- -2.2774244E-11 -0.5959606) + 0.5959606) + +(my-assert + (- -5.6623112E-11 6.8330056E9) + -6.8330056E9) + +(my-assert + (- -9.2078116E-11 -3.4236897E9) + 3.4236897E9) + +(my-assert + (- -3.317883E-11 -3.2438755E8) + 3.2438755E8) + +(my-assert + (- 6.711307E-11 -7.9204526E9) + 7.9204526E9) + +(my-assert + (- -5.1150143E-11 9.1128E9) + -9.1128E9) + +(my-assert + (- -7.3234044E-11 -8.067016E9) + 8.067016E9) + +(my-assert + (- -3.217777E-11 -1.6301262E-11) + -1.5876508E-11) + +(my-assert + (- 9.6583325E-11 5.882668E-11) + 3.7756645E-11) + +(my-assert + (- -7.573351E-11 6.3386435E-11) + -1.3911994E-10) + +(my-assert + (- -4.5759726E-11 8.069604E-11) + -1.2645576E-10) + +(my-assert + (- -9.538651E-11 -9.01152E-11) + -5.271311E-12) + +(my-assert + (- 6.2486766E-11 -3.414284E-11) + 9.662961E-11) + +(my-assert + (- 5.530477E-13 -3.1361222E18) + 3.1361222E18) + +(my-assert + (- 1.7998643E-11 1.5437615E19) + -1.5437615E19) + +(my-assert + (- -4.7948378E-11 2.6669319E19) + -2.6669319E19) + +(my-assert + (- -6.8626884E-12 -5.7713735E19) + 5.7713735E19) + +(my-assert + (- 6.195949E-11 2.8851469E19) + -2.8851469E19) + +(my-assert + (- 2.4957127E-11 -2.661574E18) + 2.661574E18) + +(my-assert + (- 9.8157565E-11 -4.561507E-21) + 9.8157565E-11) + +(my-assert + (- -9.332288E-11 -9.280375E-21) + -9.332288E-11) + +(my-assert + (- -9.916877E-11 -1.6945641E-21) + -9.916877E-11) + +(my-assert + (- -6.460804E-11 -3.6695186E-21) + -6.460804E-11) + +(my-assert + (- 6.712223E-11 -2.5360524E-21) + 6.712223E-11) + +(my-assert + (- 2.3824066E-11 -7.439168E-21) + 2.3824066E-11) + +(my-assert + (- -5.189389E19 0.01453203) + -5.189389E19) + +(my-assert + (- 7.0132006E19 0.45530832) + 7.0132006E19) + +(my-assert + (- 2.9365046E19 0.36346745) + 2.9365046E19) + +(my-assert + (- -4.1377934E19 0.37368965) + -4.1377934E19) + +(my-assert + (- -1.891423E19 0.159002) + -1.891423E19) + +(my-assert + (- 1.8096083E19 -0.6511793) + 1.8096083E19) + +(my-assert + (- 6.4361307E19 6.6511677E9) + 6.4361307E19) + +(my-assert + (- -1.8698508E19 1.1925399E9) + -1.8698508E19) + +(my-assert + (- 7.75824E19 7.7361823E9) + 7.75824E19) + +(my-assert + (- -7.2570015E19 3.0842496E9) + -7.2570015E19) + +(my-assert + (- -1.9014525E19 -3.8941514E9) + -1.9014525E19) + +(my-assert + (- 3.2787157E19 -8.612244E9) + 3.2787157E19) + +(my-assert + (- 6.4268583E19 -1.2707472E-11) + 6.4268583E19) + +(my-assert + (- -6.5179933E19 8.61941E-11) + -6.5179933E19) + +(my-assert + (- -8.106952E19 2.1709537E-11) + -8.106952E19) + +(my-assert + (- 2.5455064E19 3.5653924E-11) + 2.5455064E19) + +(my-assert + (- 1.574235E19 -2.7033407E-11) + 1.574235E19) + +(my-assert + (- -1.1099541E19 -8.620364E-12) + -1.1099541E19) + +(my-assert + (- -6.346294E19 2.9902512E19) + -9.336545E19) + +(my-assert + (- 4.9783164E19 -2.079425E19) + 7.0577414E19) + +(my-assert + (- -7.149202E19 1.4282865E19) + -8.577488E19) + +(my-assert + (- 6.0978866E19 5.256896E19) + 8.409905E18) + +(my-assert + (- -9.961146E19 -1.9834548E19) + -7.977691E19) + +(my-assert + (- 2.5196015E18 5.0534214E19) + -4.8014613E19) + +(my-assert + (- -3.6981453E19 -1.005367E-21) + -3.6981453E19) + +(my-assert + (- 8.881044E19 -9.717088E-22) + 8.881044E19) + +(my-assert + (- 4.9637263E19 -7.544846E-21) + 4.9637263E19) + +(my-assert + (- -4.2414725E19 1.3904184E-21) + -4.2414725E19) + +(my-assert + (- 7.844454E18 -8.659333E-21) + 7.844454E18) + +(my-assert + (- 1.5733016E19 8.638849E-21) + 1.5733016E19) + +(my-assert + (- 1.7531192E-21 -0.8690463) + 0.8690463) + +(my-assert + (- 9.449351E-21 0.7848489) + -0.7848489) + +(my-assert + (- 5.5016538E-21 -0.8998171) + 0.8998171) + +(my-assert + (- -6.977279E-21 -0.9815793) + 0.9815793) + +(my-assert + (- -7.9253305E-21 -0.21357381) + 0.21357381) + +(my-assert + (- 4.026555E-21 0.5610563) + -0.5610563) + +(my-assert + (- -7.080433E-21 -1.9501078E9) + 1.9501078E9) + +(my-assert + (- -8.152211E-21 8.164317E9) + -8.164317E9) + +(my-assert + (- 2.177096E-21 -8.591886E9) + 8.591886E9) + +(my-assert + (- 9.387247E-21 3.5730028E9) + -3.5730028E9) + +(my-assert + (- -7.589234E-21 -4.9193774E9) + 4.9193774E9) + +(my-assert + (- 1.5755653E-21 -2.3484498E9) + 2.3484498E9) + +(my-assert + (- 9.3034425E-21 8.28104E-11) + -8.28104E-11) + +(my-assert + (- -6.417297E-21 -8.352926E-11) + 8.352926E-11) + +(my-assert + (- 8.728735E-21 9.160732E-11) + -9.160732E-11) + +(my-assert + (- 3.8984202E-21 6.5116944E-12) + -6.5116944E-12) + +(my-assert + (- 6.288995E-21 -5.6701328E-11) + 5.6701328E-11) + +(my-assert + (- -2.7652023E-22 -1.01428276E-11) + 1.01428276E-11) + +(my-assert + (- 4.7200214E-21 -3.726995E18) + 3.726995E18) + +(my-assert + (- -2.2945808E-21 -7.3098524E19) + 7.3098524E19) + +(my-assert + (- -9.493033E-21 3.4235436E19) + -3.4235436E19) + +(my-assert + (- 3.7946773E-21 -5.126768E18) + 5.126768E18) + +(my-assert + (- -1.2865209E-21 3.5096026E19) + -3.5096026E19) + +(my-assert + (- -8.403449E-21 5.704743E18) + -5.704743E18) + +(my-assert + (- 2.928304E-21 -5.574477E-21) + 8.502781E-21) + +(my-assert + (- -9.46122E-21 -3.858943E-21) + -5.602277E-21) + +(my-assert + (- 7.296878E-22 1.8123137E-21) + -1.0826259E-21) + +(my-assert + (- 5.866651E-21 2.4605584E-21) + 3.4060923E-21) + +(my-assert + (- -7.633577E-21 9.915102E-21) + -1.7548679E-20) + +(my-assert + (- -8.7881085E-24 3.001468E-21) + -3.0102563E-21) + +;; ---- Test von * --- + +(my-assert + (* 0.3098436 0.0057770014) + 0.001789967) + +(my-assert + (* -0.14583993 -0.028087378) + 0.004096261) + +(my-assert + (* 0.21399558 0.96054405) + 0.20555218) + +(my-assert + (* 0.7590452 0.8427266) + 0.6396676) + +(my-assert + (* -0.34523207 0.20272356) + -0.06998668) + +(my-assert + (* -0.98096234 0.98158866) + -0.96290153) + +(my-assert + (* 0.40309322 4.0009994E9) + 1.6127757E9) + +(my-assert + (* 0.15507132 9.481803E9) + 1.4703557E9) + +(my-assert + (* 0.5218476 -2.1933102E9) + -1.1445737E9) + +(my-assert + (* 0.17258328 2.6295781E8) + 4.538212E7) + +(my-assert + (* 0.25962013 8.699164E9) + 2.258478E9) + +(my-assert + (* 0.47902477 -1.4075732E9) + -6.7426246E8) + +(my-assert + (* 0.9642294 -1.6256952E-11) + -1.5675431E-11) + +(my-assert + (* 0.6098744 -8.802921E-12) + -5.3686764E-12) + +(my-assert + (* -0.25792134 4.804327E-11) + -1.2391385E-11) + +(my-assert + (* -0.8724403 -9.101418E-11) + 7.940444E-11) + +(my-assert + (* -0.13318628 8.1157005E-11) + -1.08089995E-11) + +(my-assert + (* -0.54116476 -9.353639E-11) + 5.0618596E-11) + +(my-assert + (* 0.9018487 7.411783E19) + 6.6843068E19) + +(my-assert + (* -0.6835444 -7.590606E19) + 5.188516E19) + +(my-assert + (* -0.9896146 5.195105E18) + -5.141152E18) + +(my-assert + (* -0.4838531 1.88174E19) + -9.1048573E18) + +(my-assert + (* -0.31826657 -3.3103586E19) + 1.0535765E19) + +(my-assert + (* 0.6818549 -9.227651E19) + -6.2919192E19) + +(my-assert + (* 0.7676919 7.320194E-21) + 5.6196534E-21) + +(my-assert + (* 0.49369502 4.9805288E-21) + 2.4588622E-21) + +(my-assert + (* 0.9599328 7.903804E-21) + 7.58712E-21) + +(my-assert + (* 0.13215566 7.603894E-21) + 1.0048976E-21) + +(my-assert + (* -0.35744518 -9.408464E-21) + 3.36301E-21) + +(my-assert + (* -0.79346496 9.006081E-21) + -7.146009E-21) + +(my-assert + (* 4.1775434E9 -0.13509268) + -5.643555E8) + +(my-assert + (* 7.27846E9 -0.8181822) + -5.9551063E9) + +(my-assert + (* 2.9669427E9 0.7082195) + 2.1012467E9) + +(my-assert + (* 7.609933E9 -0.33963126) + -2.5845711E9) + +(my-assert + (* 3.4241843E9 0.3924479) + 1.3438139E9) + +(my-assert + (* -3.8366538E9 0.56461394) + -2.1662282E9) + +(my-assert + (* 3.7237007E9 1.2646783E9) + 4.7092836E18) + +(my-assert + (* -2.7657871E9 -3.6314278E9) + 1.0043756E19) + +(my-assert + (* -4.753982E9 -5.8879616E8) + 2.7991263E18) + +(my-assert + (* 8.877933E9 7.973602E9) + 7.07891E19) + +(my-assert + (* -8.312081E9 -8.941637E9) + 7.432361E19) + +(my-assert + (* -4.297749E9 9.913122E9) + -4.260411E19) + +(my-assert + (* -7.893335E9 -4.7961794E-11) + 0.3785785) + +(my-assert + (* -4.1332334E9 7.221582E-11) + -0.29848483) + +(my-assert + (* 1.9981688E9 2.8169871E-11) + 0.056288157) + +(my-assert + (* -5.8555295E9 -7.562528E-11) + 0.44282603) + +(my-assert + (* 7.377872E9 -1.5020383E-11) + -0.11081846) + +(my-assert + (* 8.891134E9 -7.035395E-11) + -0.6255264) + +(my-assert + (* -7.1412096E9 5.1873507E19) + -3.7043958E29) + +(my-assert + (* 8.0983844E9 9.136914E19) + 7.399425E29) + +(my-assert + (* -6.1437537E9 -9.398771E19) + 5.7743737E29) + +(my-assert + (* -2.3000973E9 6.8743785E19) + -1.5811739E29) + +(my-assert + (* 3.5817969E9 -6.0353143E19) + -2.161727E29) + +(my-assert + (* 6.544234E9 8.265139E19) + 5.4089003E29) + +(my-assert + (* 2.1273733E8 -2.3684083E-21) + -5.0384886E-13) + +(my-assert + (* -4.2644698E9 2.956708E-21) + -1.2608792E-11) + +(my-assert + (* -5.1238026E9 5.341445E-21) + -2.7368509E-11) + +(my-assert + (* -3.0125368E9 5.201843E-21) + -1.5670742E-11) + +(my-assert + (* -4.4709827E9 -1.5399217E-22) + 6.8849635E-13) + +(my-assert + (* -4.934225E9 5.9229795E-21) + -2.9225313E-11) + +(my-assert + (* -2.1100623E-11 0.9615048) + -2.028835E-11) + +(my-assert + (* 6.6090705E-12 0.4100405) + 2.7099865E-12) + +(my-assert + (* -9.541609E-11 0.82497185) + -7.871559E-11) + +(my-assert + (* -2.7884627E-11 -0.5218528) + 1.4551671E-11) + +(my-assert + (* 9.180904E-13 -0.26436818) + -2.4271386E-13) + +(my-assert + (* 2.6154882E-11 0.2004636) + 5.2431015E-12) + +(my-assert + (* 9.751009E-11 -7.0098227E9) + -0.6835284) + +(my-assert + (* -1.312651E-11 1.9450307E8) + -0.0025531466) + +(my-assert + (* -4.591856E-11 -4.6141565E8) + 0.021187542) + +(my-assert + (* -4.1950752E-11 -9.55923E9) + 0.4010169) + +(my-assert + (* -2.1888996E-11 9.976215E9) + -0.21836932) + +(my-assert + (* 4.2696267E-11 -7.927695E9) + -0.33848298) + +(my-assert + (* 1.9615304E-11 -5.3584637E-12) + -1.05107896E-22) + +(my-assert + (* -8.7289814E-11 3.4389686E-11) + -3.0018693E-21) + +(my-assert + (* 6.8621386E-11 -1.4248663E-11) + -9.77763E-22) + +(my-assert + (* -9.5643375E-11 -7.7591066E-11) + 7.421071E-21) + +(my-assert + (* -6.3313584E-11 5.173857E-11) + -3.2757542E-21) + +(my-assert + (* -6.968663E-11 -4.966581E-12) + 3.461043E-22) + +(my-assert + (* 7.942278E-11 -3.1309486E19) + -2.4866865E9) + +(my-assert + (* 1.7023414E-11 2.5512804E19) + 4.34315E8) + +(my-assert + (* 2.6554937E-11 9.146128E19) + 2.4287485E9) + +(my-assert + (* 9.309172E-13 -3.6298406E19) + -3.3790812E7) + +(my-assert + (* -6.106873E-11 3.5271824E18) + -2.1540056E8) + +(my-assert + (* -2.8420502E-11 -6.6643682E19) + 1.8940468E9) + +(my-assert + (* -5.84991E-11 1.5304011E-21) + -8.952709E-32) + +(my-assert + (* 6.30787E-11 -9.366236E-21) + -5.9081004E-31) + +(my-assert + (* 1.9745445E-11 7.034156E-21) + 1.3889253E-31) + +(my-assert + (* 2.440728E-11 6.50959E-22) + 1.5888139E-32) + +(my-assert + (* 6.0243255E-11 -1.7734902E-21) + -1.0684082E-31) + +(my-assert + (* 1.0381073E-11 7.167948E-21) + 7.441099E-32) + +(my-assert + (* 6.3378214E18 0.022634745) + 1.43454966E17) + +(my-assert + (* 5.4942345E19 0.26696533) + 1.4667702E19) + +(my-assert + (* 9.807893E19 -0.99720424) + -9.780473E19) + +(my-assert + (* -7.1504E18 0.045440495) + -3.249177E17) + +(my-assert + (* -7.265508E19 0.37276286) + -2.7083115E19) + +(my-assert + (* 9.3705245E19 0.6617385) + 6.200837E19) + +(my-assert + (* 7.768628E19 1.37205E9) + 1.0658947E29) + +(my-assert + (* 1.5640021E18 9.344063E9) + 1.4614135E28) + +(my-assert + (* 3.8593804E19 -9.424651E8) + -3.6373312E28) + +(my-assert + (* -9.23689E19 -6.980498E9) + 6.447809E29) + +(my-assert + (* 7.926599E19 5.0871127E9) + 4.0323505E29) + +(my-assert + (* 3.540541E19 -5.11486E9) + -1.810937E29) + +(my-assert + (* -7.023858E19 6.959093E-11) + -4.8879683E9) + +(my-assert + (* -2.0809586E19 -4.045683E-12) + 8.418899E7) + +(my-assert + (* 5.3608545E19 -7.0354486E-11) + -3.7716017E9) + +(my-assert + (* 8.974303E19 -6.383404E-11) + -5.72866E9) + +(my-assert + (* -6.8900017E19 9.845904E-11) + -6.7838295E9) + +(my-assert + (* 9.325442E19 -3.9829796E-11) + -3.7143045E9) + +(my-assert + (* 5.9436735E19 -5.713992E-21) + -0.33962104) + +(my-assert + (* 7.266224E18 8.9780915E-21) + 0.06523682) + +(my-assert + (* -3.6717237E18 3.3338123E-21) + -0.012240837) + +(my-assert + (* 4.119367E19 -7.309974E-21) + -0.30112466) + +(my-assert + (* -8.453134E19 4.6281215E-22) + -0.03912213) + +(my-assert + (* -3.7493624E19 5.480264E-21) + -0.20547494) + +(my-assert + (* 6.3693945E-21 -0.25352144) + -1.6147781E-21) + +(my-assert + (* -8.51531E-21 0.6031129) + -5.135693E-21) + +(my-assert + (* -9.771993E-21 0.2740926) + -2.678431E-21) + +(my-assert + (* -4.2903415E-21 0.5916119) + -2.5382172E-21) + +(my-assert + (* -3.7330673E-21 0.9738175) + -3.6353263E-21) + +(my-assert + (* 5.860415E-21 -0.9997709) + -5.8590725E-21) + +(my-assert + (* -9.4827234E-21 7.6195564E9) + -7.225415E-11) + +(my-assert + (* 5.9501194E-21 9.102942E9) + 5.4163594E-11) + +(my-assert + (* 2.8867428E-21 -9.615872E9) + -2.7758549E-11) + +(my-assert + (* 5.0077543E-21 7.8715663E9) + 3.941887E-11) + +(my-assert + (* 7.082003E-21 4.5221494E9) + 3.2025875E-11) + +(my-assert + (* -2.9215627E-21 5.131017E9) + -1.4990589E-11) + +(my-assert + (* -9.1914904E-21 -2.3301847E-11) + 2.141787E-31) + +(my-assert + (* 1.3389891E-21 -7.032628E-11) + -9.4166125E-32) + +(my-assert + (* -8.540776E-21 3.052019E-11) + -2.6066613E-31) + +(my-assert + (* -2.7608417E-21 -6.8345785E-12) + 1.886919E-32) + +(my-assert + (* 1.2978333E-21 -2.1870255E-12) + -2.8383944E-33) + +(my-assert + (* 8.2235335E-23 -3.5080876E-11) + -2.8848876E-33) + +(my-assert + (* -3.958064E-21 8.038726E19) + -0.3181779) + +(my-assert + (* 7.752178E-21 1.0747784E19) + 0.08331874) + +(my-assert + (* -5.5964265E-21 -8.700492E19) + 0.48691663) + +(my-assert + (* 3.2236927E-21 3.6203593E19) + 0.116709255) + +(my-assert + (* -6.308517E-21 -3.8032156E19) + 0.2399265) + +(my-assert + (* 4.8663387E-21 9.008218E19) + 0.43837038) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.8227301 -0.25283414)) + (3 -0.06422769)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.6686161 0.4833234)) + (-2 0.29803064)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.57436657 0.52642506)) + (-2 0.47848356)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.60395426 -0.61624163)) + (-1 -0.012287392)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.21636301 0.90365344)) + (-1 0.68729043)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.8705054 -0.7953333)) + (-2 -0.72016126)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.4544462 -9.890925E9)) + (-1 -9.890925E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.4954149 -3.8786918E9)) + (0 -0.49541488)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.692049 6.4791506E9)) + (-1 6.4791506E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.75464755 -3.618496E9)) + (-1 -3.618496E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.5929247 -5.442471E9)) + (0 -0.5929247)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.30383867 9.262864E9)) + (-1 9.262864E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.9345329 3.26737E-11)) + (28601991168 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.3772617 -7.991702E-11)) + (-4720667648 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.74438447 -1.0977978E-11)) + (-67807064064 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9220973 -1.2655998E-11)) + (72858525696 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.4615329 6.48833E-11)) + (-7113276928 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.2851941 -8.262349E-11)) + (-3451731456 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.61539984 3.5826177E19)) + (0 0.61539984)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.8195054 8.793426E19)) + (-1 8.793426E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.26412165 7.015103E18)) + (-1 7.015103E18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.527393 8.434833E19)) + (-1 8.434833E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.1846056 1.8252128E19)) + (-1 1.8252128E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.6079822 6.106683E19)) + (-1 6.106683E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.5564819 5.953872E-21)) + (93465542827563810816 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.52575815 -1.8358678E-21)) + (286381261476583178240 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.6321403 -5.830945E-21)) + (108411292344853200896 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9675891 -9.936226E-21)) + (97379936163841703936 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.63503754 -5.0137436E-21)) + (126659359065470140416 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.8053654 -3.4055888E-22)) + (-2364834534832713236480 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.784645E9 0.9775517)) + (8986374144 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.314413E9 -0.8318871)) + (11196726272 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.4695936E9 -0.9823455)) + (-8621807616 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.8406625E9 -0.031723082)) + (184113971200 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.325545E9 0.93169844)) + (-7862571008 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.2999526E9 0.11515945)) + (-46022733824 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.680458E9 7.170729E9)) + (0 6.680458E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.2146278E9 5.2909993E9)) + (-1 3.0763715E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.4947005E9 3.1265188E9)) + (2 2.4166298E8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.947109E9 2.464481E9)) + (3 5.53666E8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.899791E9 3.5788132E9)) + (2 1.7421644E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.272568E9 -5.3260964E9)) + (-1 -5.3528532E7)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.729838E8 8.6379175E-11)) + (11264101901890748416 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.210882E9 -4.412428E-11)) + (-27442532596777484288 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.169561E9 -9.41537E-11)) + (-97389277614631288832 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.289745E9 3.1269442E-11)) + (297087021478284623872 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.334722E9 2.0158666E-11)) + (-264636651022615314432 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.910798E9 -2.985589E-11)) + (-331954558296456691712 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.7169357E9 2.220112E19)) + (-1 2.220112E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.9906683E9 6.857979E19)) + (0 4.9906683E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.90463E9 -2.342953E19)) + (0 -9.90463E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.4878054E8 5.438576E19)) + (-1 5.438576E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.1080986E9 9.25119E19)) + (-1 9.25119E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.4138286E9 -9.682224E19)) + (0 -8.4138286E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.7084977E9 2.542436E-23)) + (106531597407755826831748572905472 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.720767E9 9.438407E-21)) + (-606115738076318963177881600000 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.4958034E9 9.250327E-21)) + (-377911344579488968728001904640 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.3702047E9 6.0186186E-21)) + (-1390718493086361392338557730816 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.517619E9 -9.417701E-21)) + (798243593937800371539149848576 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.1220838E9 3.931208E-21)) + (-539804494597454582830132625408 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.9606828E-11 0.34267086)) + (-1 0.34267086)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.495503E-11 -0.4518087)) + (-1 -0.4518087)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.98698E-11 -0.5665642)) + (0 -7.98698E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.1465689E-11 0.17276591)) + (0 2.146569E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.9463066E-11 -0.5659616)) + (-1 -0.5659616)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.8961567E-11 -0.7758364)) + (0 -1.8961567E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.8871874E-11 -5.768549E9)) + (-1 -5.768549E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.079439E-11 -3.807195E9)) + (0 -9.079439E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.879919E-12 -1.9198149E9)) + (-1 -1.9198149E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.389072E-11 -8.657572E9)) + (-1 -8.657572E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.430157E-11 -3.8599355E9)) + (-1 -3.8599355E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.8839114E-11 -5.3409536E9)) + (0 -5.8839114E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.3353615E-11 8.9096924E-11)) + (-1 5.574331E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.335122E-11 3.606541E-11)) + (1 2.7285809E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.6885465E-11 7.070333E-12)) + (-9 6.7475353E-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.581576E-11 -3.4334775E-11)) + (2 -7.1462155E-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.6686505E-11 -1.9221425E-11)) + (-2 -1.7563462E-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.066395E-11 -2.3198866E-11)) + (-2 -1.573378E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.1089344E-11 7.429058E19)) + (0 9.1089344E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.2265194E-11 -6.5831596E19)) + (0 -7.2265194E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.9087675E-11 1.9182038E19)) + (-1 1.9182038E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.907188E-11 4.405831E19)) + (-1 4.405831E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.118759E-11 3.4342181E19)) + (0 6.118759E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.4731882E-11 -5.861447E19)) + (-1 -5.861447E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.121101E-11 -1.8234462E-21)) + (-33568860160 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.788758E-11 -2.65478E-21)) + (-36872200192 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.827001E-11 -8.5754775E-21)) + (-9127189504 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.738018E-11 -7.810784E-21)) + (4785714176 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.31308E-11 -2.0431058E-21)) + (-35793936384 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.4578095E-11 -3.0466443E-21)) + (-31043366912 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.8186137E19 -0.95250696)) + (50588749896299315200 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.548003E18 -0.9061317)) + (-10537102614582001664 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.5254813E19 0.51959753)) + (106341562860634636288 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.2787504E19 0.14769173)) + (-289708190148186865664 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.27109E17 -0.03677529)) + (11614021477430460416 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.9238043E19 0.26663417)) + (-147160597790283792384 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.0174873E19 -6.7035556E7)) + (300957794304 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.6296811E19 -7.2014956E9)) + (-2262976000 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.794499E19 -7.412829E9)) + (-10514876416 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.2546485E19 6.1565005E9)) + (-2037924864 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.4549757E18 -4.778849E9)) + (-1141483264 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.9214324E18 3.0002557E9)) + (-2973557248 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.790958E19 -8.224902E-11)) + (-1068822197453670185020302557184 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.029222E18 1.3127345E-11)) + (687817816164697187548814901248 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.7356843E19 -9.1816894E-11)) + (-733599685837775742566290948096 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.0346153E19 2.0593792E-11)) + (1959141510822234462049892564992 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.3402778E19 -4.8733902E-11)) + (-275019611403690085233016700928 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.3005549E19 5.6579824E-11)) + (-229861963021783171398467846144 0.0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.550302E19 6.4624324E19)) + (1 2.0878699E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.7897585E19 -1.5724218E19)) + (-4 -1.4999288E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.6050445E19 1.4007867E19)) + (-7 1.2004627E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.0799387E19 -5.667626E19)) + (1 -4.1231221E18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.847746E19 -3.972193E19)) + (1 -3.875553E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.425414E19 3.0601436E19)) + (-3 2.7550168E19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.8220074E-21 -0.9401483)) + (-1 -0.9401483)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.867747E-21 0.86288685)) + (0 9.867747E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.2856053E-21 -0.5235996)) + (-1 -0.5235996)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.709991E-22 0.42678982)) + (0 8.709991E-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.0493481E-21 0.9355661)) + (0 1.0493481E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.137466E-21 0.4328317)) + (-1 0.4328317)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.5872774E-21 -8.80464E9)) + (-1 -8.80464E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.0479629E-22 -9.353607E9)) + (0 -1.0479629E-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.636932E-21 9.794678E9)) + (-1 9.794678E9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.912024E-21 -2.9102356E9)) + (0 -7.912024E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.0071349E-21 8.762459E9)) + (0 1.0071349E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.795979E-21 -9.445545E9)) + (0 -6.795979E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.0598967E-22 -3.961637E-11)) + (-1 -3.961637E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.481348E-21 -7.485006E-11)) + (-1 -7.485006E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.610974E-21 -4.073898E-11)) + (0 -5.610974E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.2362584E-21 8.403202E-11)) + (-1 8.403202E-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.2029927E-21 7.823452E-11)) + (0 4.2029927E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.765272E-21 -8.502908E-11)) + (0 -7.765272E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.7845436E-21 3.490416E-21)) + (0 2.7845436E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.4630091E-21 9.193901E-21)) + (-1 7.730892E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.1823826E-21 8.941324E-21)) + (-1 7.5894165E-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.8218875E-21 3.8057304E-21)) + (-1 1.9838427E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.8037763E-21 -5.1721612E-21)) + (-2 -4.5405462E-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.179982E-21 6.2204556E-21)) + (-2 4.2609293E-21)) + +;; ---- Test von / --- + +(my-assert + (/ 0.73739415 0.6416277) + 1.1492554) + +(my-assert + (/ 0.6736158 -0.25522494) + -2.6393025) + +(my-assert + (/ -0.44216943 0.31134832) + -1.420176) + +(my-assert + (/ -0.7041118 -0.26929635) + 2.6146355) + +(my-assert + (/ 0.3573562 0.73521775) + 0.4860549) + +(my-assert + (/ -0.7661392 0.77110463) + -0.9935606) + +(my-assert + (/ -0.91306114 1.6586358E9) + -5.504892E-10) + +(my-assert + (/ -0.68994707 4.0230333E8) + -1.7149921E-9) + +(my-assert + (/ 0.28498656 -7.617844E9) + -3.7410394E-11) + +(my-assert + (/ -0.72419757 -9.226896E9) + 7.848767E-11) + +(my-assert + (/ 0.8352187 8.3102536E9) + 1.00504605E-10) + +(my-assert + (/ 0.9707725 3.3669448E9) + 2.8832445E-10) + +(my-assert + (/ 0.50785017 6.048824E-11) + 8.3958497E9) + +(my-assert + (/ -0.17675805 4.1391092E-11) + -4.270437E9) + +(my-assert + (/ -0.42162335 -4.4007357E-11) + 9.580747E9) + +(my-assert + (/ -7.945299E-4 -5.4965265E-11) + 1.4455128E7) + +(my-assert + (/ -0.65178335 -9.78151E-12) + 6.6634228E10) + +(my-assert + (/ -0.6209788 -3.8544803E-11) + 1.611057E10) + +(my-assert + (/ 0.94332725 -4.9823833E19) + -1.8933253E-20) + +(my-assert + (/ 0.30150706 -4.9741757E19) + -6.061448E-21) + +(my-assert + (/ -0.8478371 -9.85865E18) + 8.5999306E-20) + +(my-assert + (/ -0.28524554 3.1389898E19) + -9.087176E-21) + +(my-assert + (/ -0.5260848 -7.936286E19) + 6.6288534E-21) + +(my-assert + (/ -0.12941593 -5.3575864E19) + 2.415564E-21) + +(my-assert + (/ -0.20859545 -9.867267E-21) + 2.1140145E19) + +(my-assert + (/ 0.35158414 -8.2825064E-22) + -4.2449002E20) + +(my-assert + (/ -0.05635804 -2.2999601E-21) + 2.450392E19) + +(my-assert + (/ -0.003138721 -3.3988403E-21) + 9.234682E17) + +(my-assert + (/ -0.91386896 -5.8199337E-21) + 1.5702395E20) + +(my-assert + (/ -0.5374476 2.256708E-21) + -2.3815556E20) + +(my-assert + (/ 1.9669795E9 -0.58137333) + -3.3833329E9) + +(my-assert + (/ -8.9879334E8 0.35829848) + -2.5085046E9) + +(my-assert + (/ -9.057627E9 0.4849478) + -1.867753E10) + +(my-assert + (/ 3.687799E8 -0.34055912) + -1.082866E9) + +(my-assert + (/ -5.1049994E9 -0.16858816) + 3.0280888E10) + +(my-assert + (/ -4.512774E9 0.9385354) + -4.8083154E9) + +(my-assert + (/ -1.9312024E9 -8.3940613E9) + 0.2300677) + +(my-assert + (/ -8.2104387E9 6.769607E9) + -1.2128383) + +(my-assert + (/ -6.9613486E9 4.576518E9) + -1.5211015) + +(my-assert + (/ -1.486333E9 1.2476433E9) + -1.1913126) + +(my-assert + (/ -7.653413E9 5.167656E9) + -1.4810221) + +(my-assert + (/ -2.9815204E9 8.942396E9) + -0.33341402) + +(my-assert + (/ 9.304549E9 -5.8002263E-11) + -1.60417E20) + +(my-assert + (/ -2.0750719E9 1.272735E-11) + -1.6304037E20) + +(my-assert + (/ -1.1557549E9 -7.2220556E-11) + 1.6003129E19) + +(my-assert + (/ -3.3273495E9 -9.9207274E-11) + 3.353937E19) + +(my-assert + (/ -3.2167434E9 7.7474506E-11) + -4.1520026E19) + +(my-assert + (/ 4.4169416E9 -4.638272E-11) + -9.5228166E19) + +(my-assert + (/ -3.732909E9 -2.2763849E18) + 1.6398409E-9) + +(my-assert + (/ -6.243126E9 -4.1274483E19) + 1.5125873E-10) + +(my-assert + (/ 4.7162563E9 -7.524631E19) + -6.267758E-11) + +(my-assert + (/ -1.3657349E9 7.728982E19) + -1.7670308E-11) + +(my-assert + (/ -4.6216906E8 -7.972877E19) + 5.7967663E-12) + +(my-assert + (/ 4.4542986E9 3.1531836E19) + 1.4126353E-10) + +(my-assert + (/ 1.4738977E9 -9.8130876E-21) + -1.5019714E29) + +(my-assert + (/ -5.918336E9 2.9877495E-21) + -1.9808676E30) + +(my-assert + (/ -3.7166292E9 -1.0826009E-21) + 3.433056E30) + +(my-assert + (/ 7.390683E9 -2.1678685E-22) + -3.4091935E31) + +(my-assert + (/ 6.2302886E8 8.9466635E-21) + 6.963812E28) + +(my-assert + (/ 5.2357125E9 4.854464E-22) + 1.0785356E31) + +(my-assert + (/ -2.7721167E-11 0.99550104) + -2.7846447E-11) + +(my-assert + (/ 5.754337E-11 -0.6344538) + -9.06975E-11) + +(my-assert + (/ -7.663363E-11 0.020810604) + -3.6824317E-9) + +(my-assert + (/ 3.2576632E-11 0.6209498) + 5.2462586E-11) + +(my-assert + (/ -9.507874E-11 -0.19174337) + 4.958645E-10) + +(my-assert + (/ -9.681176E-11 -0.82680905) + 1.1709084E-10) + +(my-assert + (/ 6.458532E-11 3.442031E8) + 1.8763725E-19) + +(my-assert + (/ 1.9113166E-11 -7.0712125E9) + -2.7029546E-21) + +(my-assert + (/ -2.0099402E-12 2.600844E9) + -7.7280303E-22) + +(my-assert + (/ -4.9634992E-12 8.041176E9) + -6.1726036E-22) + +(my-assert + (/ 3.2738747E-12 7.299675E9) + 4.484959E-22) + +(my-assert + (/ 9.133733E-12 -2.6318538E9) + -3.470456E-21) + +(my-assert + (/ -3.4146054E-11 -1.5331155E-11) + 2.227233) + +(my-assert + (/ 6.06336E-11 4.3750472E-11) + 1.385896) + +(my-assert + (/ -4.229064E-11 -9.169808E-11) + 0.4611944) + +(my-assert + (/ 6.166104E-11 -3.5474658E-11) + -1.7381715) + +(my-assert + (/ -3.979801E-11 -1.9510412E-11) + 2.0398343) + +(my-assert + (/ 9.726933E-11 -5.6926824E-11) + -1.7086731) + +(my-assert + (/ 8.041786E-11 2.3718388E19) + 3.3905282E-30) + +(my-assert + (/ -6.747094E-11 -6.7324465E19) + 1.0021756E-30) + +(my-assert + (/ -3.0713255E-11 -4.8310887E19) + 6.357419E-31) + +(my-assert + (/ -2.8496396E-11 -4.9017306E19) + 5.813538E-31) + +(my-assert + (/ -9.354275E-12 -9.035095E19) + 1.0353266E-31) + +(my-assert + (/ 4.9274265E-12 7.241873E19) + 6.8040775E-32) + +(my-assert + (/ -4.377009E-11 7.138917E-21) + -6.131195E9) + +(my-assert + (/ 9.422678E-12 -5.8862136E-21) + -1.6008046E9) + +(my-assert + (/ -6.83782E-11 -3.6098812E-21) + 1.8941952E10) + +(my-assert + (/ -8.1755075E-11 -6.8725736E-21) + 1.1895846E10) + +(my-assert + (/ -6.360949E-11 4.2976342E-21) + -1.4801049E10) + +(my-assert + (/ 3.3879413E-11 -1.7169743E-21) + -1.9732044E10) + +(my-assert + (/ -9.948093E18 -0.8695114) + 1.1441014E19) + +(my-assert + (/ 6.2748975E19 -0.94829553) + -6.6170272E19) + +(my-assert + (/ -6.204444E18 0.6874813) + -9.0248915E18) + +(my-assert + (/ 6.7599936E19 -0.45808762) + -1.4756988E20) + +(my-assert + (/ 7.624068E19 0.008471012) + 9.0001855E21) + +(my-assert + (/ 8.342225E19 -0.3031574) + -2.7517803E20) + +(my-assert + (/ -6.3366795E19 -1.4882481E9) + 4.2578113E10) + +(my-assert + (/ -1.7335874E19 -7.42875E9) + 2.3336195E9) + +(my-assert + (/ -8.662651E19 1.0327226E9) + -8.388168E10) + +(my-assert + (/ -4.9590965E19 8.334462E9) + -5.95011E9) + +(my-assert + (/ 8.191562E18 5.930472E9) + 1.3812664E9) + +(my-assert + (/ -3.5910857E19 -7.342098E9) + 4.8910894E9) + +(my-assert + (/ -3.6083056E19 5.7372277E-11) + -6.2892843E29) + +(my-assert + (/ 2.2896613E19 -4.541202E-11) + -5.0419717E29) + +(my-assert + (/ 6.1438805E19 8.512014E-11) + 7.217893E29) + +(my-assert + (/ 6.3211746E19 -6.185377E-12) + -1.0219547E31) + +(my-assert + (/ 4.5452835E18 2.0429606E-11) + 2.2248514E29) + +(my-assert + (/ 9.226608E19 1.3297486E-11) + 6.9386104E30) + +(my-assert + (/ 1.8852943E19 -1.623413E19) + -1.1613153) + +(my-assert + (/ -3.117305E18 -9.5760065E19) + 0.03255329) + +(my-assert + (/ -7.719376E19 3.3627052E19) + -2.295585) + +(my-assert + (/ 3.1309093E19 -7.820006E19) + -0.4003717) + +(my-assert + (/ 3.941958E19 -9.51598E19) + -0.41424614) + +(my-assert + (/ -3.6364467E19 -1.0757047E19) + 3.380525) + +(my-assert + (/ 2.906561E17 -8.595159E-21) + -3.3816258E37) + +(my-assert + (/ -7.826226E-21 -0.21695328) + 3.6073327E-20) + +(my-assert + (/ -1.888169E-21 0.5031878) + -3.7524144E-21) + +(my-assert + (/ 8.304594E-21 -0.3528648) + -2.3534775E-20) + +(my-assert + (/ -8.441606E-21 -0.3639353) + 2.3195348E-20) + +(my-assert + (/ -7.815205E-21 0.38263506) + -2.0424697E-20) + +(my-assert + (/ -3.2837188E-21 0.46961308) + -6.992392E-21) + +(my-assert + (/ -5.1739832E-21 -3.8917279E9) + 1.3294822E-30) + +(my-assert + (/ -5.3318596E-21 -7.1995423E9) + 7.405831E-31) + +(my-assert + (/ -7.4979364E-22 9.148773E9) + -8.195565E-32) + +(my-assert + (/ 4.6800053E-21 3.9532006E8) + 1.1838522E-29) + +(my-assert + (/ 4.914653E-22 -2.414465E9) + -2.035504E-31) + +(my-assert + (/ 5.4722133E-21 -9.977777E9) + -5.484401E-31) + +(my-assert + (/ 9.815656E-21 6.059642E-11) + 1.619841E-10) + +(my-assert + (/ 7.660357E-21 9.7074675E-11) + 7.891201E-11) + +(my-assert + (/ 9.77743E-21 2.5170428E-11) + 3.8844908E-10) + +(my-assert + (/ 8.818017E-21 1.18070545E-11) + 7.468431E-10) + +(my-assert + (/ 5.445426E-21 9.6208916E-11) + 5.6600016E-11) + +(my-assert + (/ 4.6823916E-21 -1.9853067E-11) + -2.358523E-10) + +(my-assert + (/ 9.347429E-21 -7.285392E-22) + -12.830372) + +(my-assert + (/ -7.304412E-21 6.766496E-21) + -1.079497) + +(my-assert + (/ -2.6850204E-21 6.894023E-21) + -0.38947076) + +(my-assert + (/ -2.24644E-21 -9.533858E-21) + 0.23562758) + +(my-assert + (/ -8.525939E-21 -9.961187E-22) + 8.559159) + +(my-assert + (/ 8.145676E-21 4.304153E-22) + 18.925154) + +;; ==== D O U B L E - F L O A T S ==== + +;; ---- Test von + --- + +(my-assert + (+ 0.6049332056786565d0 -0.9611373574853808d0) + -0.35620415180672427d0) + +(my-assert + (+ -0.4763715667865308d0 0.25936932107685584d0) + -0.21700224570967497d0) + +(my-assert + (+ 0.2666481927718355d0 -0.04984768063142031d0) + 0.21680051214041518d0) + +(my-assert + (+ -0.29478659758474846d0 0.3371004337672615d0) + 0.042313836182513054d0) + +(my-assert + (+ 0.8203063910979178d0 0.28968607542857916d0) + 1.109992466526497d0) + +(my-assert + (+ -0.08207985138263585d0 0.4368723951711785d0) + 0.35479254378854264d0) + +(my-assert + (+ -0.8659875373355486d0 -6.631430771196765d9) + -6.631430772062753d9) + +(my-assert + (+ 0.15071385783307878d0 -7.154424279496395d9) + -7.154424279345681d9) + +(my-assert + (+ -0.8969642760814789d0 -2.4070067380831727d8) + -2.4070067470528156d8) + +(my-assert + (+ -0.9610362081435054d0 9.070410778399954d9) + 9.070410777438917d9) + +(my-assert + (+ 0.5129052501104072d0 -7.47841120327471d9) + -7.478411202761805d9) + +(my-assert + (+ 0.3840242289740675d0 7.793048210060242d9) + 7.793048210444266d9) + +(my-assert + (+ 0.07603066126204616d0 5.215008470388369d-11) + 0.07603066131419625d0) + +(my-assert + (+ -0.17187858025312586d0 -5.116645189173968d-11) + -0.17187858030429232d0) + +(my-assert + (+ 0.2521315816245864d0 8.603210607505339d-11) + 0.2521315817106185d0) + +(my-assert + (+ -0.3557185853193914d0 -2.0371324697272998d-11) + -0.3557185853397627d0) + +(my-assert + (+ 0.7142792289542045d0 -7.106356053331326d-11) + 0.7142792288831409d0) + +(my-assert + (+ 0.4380415886629452d0 -3.069969538383403d-11) + 0.43804158863224546d0) + +(my-assert + (+ 0.24798614227178573d0 3.972393639614975d19) + 3.972393639614975d19) + +(my-assert + (+ -0.5210677288128815d0 4.846393336901129d19) + 4.846393336901129d19) + +(my-assert + (+ 0.5825404819115d0 1.9710987361264255d19) + 1.9710987361264255d19) + +(my-assert + (+ 0.9105175208730549d0 2.391166552096775d19) + 2.391166552096775d19) + +(my-assert + (+ 0.48414423368371695d0 -9.696117779740095d19) + -9.696117779740095d19) + +(my-assert + (+ 0.25780758450697716d0 6.094683117025535d19) + 6.094683117025535d19) + +(my-assert + (+ 0.9824539149570484d0 -5.4680066990812835d-21) + 0.9824539149570484d0) + +(my-assert + (+ -0.9520982941158654d0 3.2513564801568073d-21) + -0.9520982941158654d0) + +(my-assert + (+ 0.0630170624560149d0 -9.858852595793203d-21) + 0.0630170624560149d0) + +(my-assert + (+ 0.24705141169888878d0 1.4582081178692862d-22) + 0.24705141169888878d0) + +(my-assert + (+ 0.7440948700757135d0 -3.0932442581890818d-21) + 0.7440948700757135d0) + +(my-assert + (+ -0.5055970869515372d0 4.0277457257516025d-21) + -0.5055970869515372d0) + +(my-assert + (+ 1.672355787134947d9 0.0064909681594120805d0) + 1.672355787141438d9) + +(my-assert + (+ -9.694504381396599d9 -0.8925470085542831d0) + -9.694504382289146d9) + +(my-assert + (+ -1.6695005924298635d9 -0.34426964741306d0) + -1.6695005927741332d9) + +(my-assert + (+ -6.085591212594774d9 0.5107956920100049d0) + -6.085591212083979d9) + +(my-assert + (+ 7.457486660952688d9 -0.4323787588338597d0) + 7.457486660520309d9) + +(my-assert + (+ -8.790796444526546d9 0.911415263281967d0) + -8.790796443615131d9) + +(my-assert + (+ 9.667548804251982d9 -1.266547751029956d8) + 9.540894029148987d9) + +(my-assert + (+ -6.169561898845145d9 9.627911197121864d9) + 3.458349298276719d9) + +(my-assert + (+ -9.870287253215279d9 9.004242781937655d8) + -8.969862975021513d9) + +(my-assert + (+ -8.175630881172554d9 -4.08632236263908d9) + -1.2261953243811634d10) + +(my-assert + (+ 2.9069444232153206d9 -7.961831315741894d9) + -5.054886892526573d9) + +(my-assert + (+ -7.003647401371184d9 -1.768371514817526d9) + -8.772018916188711d9) + +(my-assert + (+ -6.418847599138249d9 2.755257250162372d-11) + -6.418847599138249d9) + +(my-assert + (+ 2.3093152687241793d9 1.2205440142364766d-11) + 2.3093152687241793d9) + +(my-assert + (+ 8.634577667577518d9 -9.065714034538668d-11) + 8.634577667577518d9) + +(my-assert + (+ 1.711283212591781d9 -3.235019197733951d-11) + 1.711283212591781d9) + +(my-assert + (+ 2.583886638357791d9 -8.199109798920928d-11) + 2.583886638357791d9) + +(my-assert + (+ -7.517123950474774d9 5.2057802142431697d-11) + -7.517123950474774d9) + +(my-assert + (+ 3.266571938086574d9 -4.4782768261898355d19) + -4.478276825863179d19) + +(my-assert + (+ 2.1000389219899452d9 -8.547158903365463d19) + -8.54715890315546d19) + +(my-assert + (+ -3.9140926801217155d9 7.387959860641422d19) + 7.387959860250013d19) + +(my-assert + (+ -7.087607465790431d9 7.96875093387599d19) + 7.96875093316723d19) + +(my-assert + (+ -8.341000808926519d9 6.9360028397637304d19) + 6.93600283892963d19) + +(my-assert + (+ -5.507940634743809d9 9.760028858210094d19) + 9.7600288576593d19) + +(my-assert + (+ 8.492522971238823d9 -2.8253881864964467d-22) + 8.492522971238823d9) + +(my-assert + (+ 1.2731765723336241d9 -5.8473937102910264d-21) + 1.2731765723336241d9) + +(my-assert + (+ 9.654280758878323d9 -4.2332114049658973d-22) + 9.654280758878323d9) + +(my-assert + (+ -6.864618926120946d9 -1.245648314796599d-21) + -6.864618926120946d9) + +(my-assert + (+ -3.9916044043798673d8 1.697737588450543d-21) + -3.9916044043798673d8) + +(my-assert + (+ -7.818041624198686d9 4.635421587404246d-21) + -7.818041624198686d9) + +(my-assert + (+ 2.0609929543990767d-12 -0.2126306554359736d0) + -0.2126306554339126d0) + +(my-assert + (+ -1.5923091695877845d-11 0.515731533720818d0) + 0.515731533704895d0) + +(my-assert + (+ 4.794527092905871d-11 -0.9066947202676092d0) + -0.9066947202196639d0) + +(my-assert + (+ -8.63854477728633d-11 0.3122982022565777d0) + 0.3122982021701922d0) + +(my-assert + (+ -7.577966666552416d-11 -0.24137602092437593d0) + -0.2413760210001556d0) + +(my-assert + (+ -4.971730475882754d-11 -0.8202688719750202d0) + -0.8202688720247375d0) + +(my-assert + (+ -5.249369194379291d-11 -8.546120620321186d9) + -8.546120620321186d9) + +(my-assert + (+ 8.280786962526793d-11 5.758373397436368d9) + 5.758373397436368d9) + +(my-assert + (+ 6.370323595535815d-11 -8.470663335712393d9) + -8.470663335712393d9) + +(my-assert + (+ 3.59771226839467d-11 3.5042505440266216d8) + 3.5042505440266216d8) + +(my-assert + (+ -3.945501687396375d-11 -5.082779978069177d9) + -5.082779978069177d9) + +(my-assert + (+ 9.780590963267516d-11 -5.05591945120475d9) + -5.05591945120475d9) + +(my-assert + (+ 6.323293597096768d-11 -7.208898910487284d-11) + -8.85605313390516d-12) + +(my-assert + (+ -4.549781732354749d-11 -6.095452636416357d-11) + -1.0645234368771105d-10) + +(my-assert + (+ -5.372680267837374d-11 2.0748354219485134d-11) + -3.297844845888861d-11) + +(my-assert + (+ 3.550879553916665d-11 -4.374873254056574d-11) + -8.23993700139909d-12) + +(my-assert + (+ -6.746002242414832d-11 3.0803985031459436d-11) + -3.665603739268888d-11) + +(my-assert + (+ -7.902512161494214d-11 -8.907842858073236d-11) + -1.681035501956745d-10) + +(my-assert + (+ -4.1465935469350415d-11 6.244210696961323d19) + 6.244210696961323d19) + +(my-assert + (+ 4.921297536286578d-11 -1.694436650099881d19) + -1.694436650099881d19) + +(my-assert + (+ -7.879478980672654d-11 6.41757969360492d19) + 6.41757969360492d19) + +(my-assert + (+ -8.200749317872953d-11 -9.490225542618815d19) + -9.490225542618815d19) + +(my-assert + (+ -7.572981329795812d-11 -3.350367078181029d19) + -3.350367078181029d19) + +(my-assert + (+ -5.955255565125549d-11 -5.009913629288125d19) + -5.009913629288125d19) + +(my-assert + (+ -9.818180775332558d-11 -7.926156011681593d-21) + -9.818180776125174d-11) + +(my-assert + (+ -5.2466438379505935d-12 8.468830229031857d-21) + -5.246643829481763d-12) + +(my-assert + (+ 3.582774358441715d-11 3.6865211729351863d-22) + 3.58277435847858d-11) + +(my-assert + (+ 7.169296413565744d-11 -9.974881413980864d-21) + 7.169296412568256d-11) + +(my-assert + (+ -9.615073655516977d-11 4.9552491300097786d-21) + -9.615073655021452d-11) + +(my-assert + (+ 6.7696956269187d-11 4.1431488006404866d-21) + 6.769695627333016d-11) + +(my-assert + (+ -4.663397365185298d19 0.9758464195927673d0) + -4.663397365185298d19) + +(my-assert + (+ -4.77977261393851d19 0.04145189313162445d0) + -4.77977261393851d19) + +(my-assert + (+ 7.195364554121596d19 0.5169917736820715d0) + 7.195364554121596d19) + +(my-assert + (+ -7.766254779507882d19 0.5919134938460356d0) + -7.766254779507882d19) + +(my-assert + (+ -8.411122653901408d19 -0.14463225181516137d0) + -8.411122653901408d19) + +(my-assert + (+ -9.101920591747218d19 0.23349918704239836d0) + -9.101920591747218d19) + +(my-assert + (+ 7.037477746142529d18 -3.250947575909365d9) + 7.037477742891581d18) + +(my-assert + (+ -6.864341752972099d19 -4.0510449339565725d9) + -6.864341753377203d19) + +(my-assert + (+ -5.329540273290228d19 8.14869777458878d9) + -5.329540272475358d19) + +(my-assert + (+ -9.726234388247201d19 2.053976989398215d9) + -9.726234388041803d19) + +(my-assert + (+ -1.910324088450308d19 6.247052535748024d9) + -1.910324087825603d19) + +(my-assert + (+ -6.079933001949367d18 6.316829148809886d9) + -6.079932995632539d18) + +(my-assert + (+ -4.499107911798452d19 9.659763881732633d-11) + -4.499107911798452d19) + +(my-assert + (+ -3.0972208018542522d19 -9.077209886078653d-11) + -3.0972208018542522d19) + +(my-assert + (+ -2.3000547840875442d19 -3.2043634522621155d-11) + -2.3000547840875442d19) + +(my-assert + (+ 2.124555308489292d19 2.252166800652451d-11) + 2.124555308489292d19) + +(my-assert + (+ -7.74280238703686d19 1.7289553748884322d-11) + -7.74280238703686d19) + +(my-assert + (+ -8.119446783121816d19 -4.3461802389685114d-11) + -8.119446783121816d19) + +(my-assert + (+ -4.70848534032654d18 -4.698316648967506d19) + -5.169165183000161d19) + +(my-assert + (+ 2.853799842810312d19 -5.56805968603395d19) + -2.7142598432236384d19) + +(my-assert + (+ -2.9128622996090335d19 -5.153369106520702d19) + -8.066231406129735d19) + +(my-assert + (+ -5.415993984772977d19 4.481932558278175d19) + -9.340614264948015d18) + +(my-assert + (+ -1.4652301908531261d19 7.89284449966826d19) + 6.427614308815133d19) + +(my-assert + (+ -8.241911630479252d19 5.377001886877124d19) + -2.8649097436021277d19) + +(my-assert + (+ -6.923631123395076d19 7.100129853298664d-22) + -6.923631123395076d19) + +(my-assert + (+ -5.864213410820717d19 -2.649878514627326d-21) + -5.864213410820717d19) + +(my-assert + (+ 8.660575002861176d19 2.751926085897399d-21) + 8.660575002861176d19) + +(my-assert + (+ -3.0252871646631318d19 6.852831573716124d-21) + -3.0252871646631318d19) + +(my-assert + (+ -9.155476807340938d19 -5.552907466957205d-21) + -9.155476807340938d19) + +(my-assert + (+ -4.03382621358461d19 6.670808279457885d-21) + -4.03382621358461d19) + +(my-assert + (+ 8.842980509187577d-21 0.5028466982188534d0) + 0.5028466982188534d0) + +(my-assert + (+ 1.7292043381396136d-21 0.19490424064972922d0) + 0.19490424064972922d0) + +(my-assert + (+ -5.854820918836103d-21 -0.6700030154364615d0) + -0.6700030154364615d0) + +(my-assert + (+ -2.152396491682048d-21 0.5002930268902921d0) + 0.5002930268902921d0) + +(my-assert + (+ -1.0897149666610629d-21 0.16555534170490604d0) + 0.16555534170490604d0) + +(my-assert + (+ 6.321421497987867d-24 -0.08008112131564671d0) + -0.08008112131564671d0) + +(my-assert + (+ -6.1552667309563055d-21 7.235074489769488d9) + 7.235074489769488d9) + +(my-assert + (+ -2.2311335001219955d-22 1.220011008333989d9) + 1.220011008333989d9) + +(my-assert + (+ 8.523565724937177d-23 -4.1650242034123087d9) + -4.1650242034123087d9) + +(my-assert + (+ -2.4400041303825447d-21 4.435554678685388d9) + 4.435554678685388d9) + +(my-assert + (+ -3.4479065449345757d-22 8.491084033112451d8) + 8.491084033112451d8) + +(my-assert + (+ -7.919939059912893d-21 -7.610637842585286d9) + -7.610637842585286d9) + +(my-assert + (+ 4.4958602369105625d-21 5.758376768873417d-11) + 5.7583767693230034d-11) + +(my-assert + (+ 2.4375297386412195d-21 9.417086717671841d-11) + 9.417086717915595d-11) + +(my-assert + (+ 1.0040647133383462d-21 3.4701016271268983d-12) + 3.470101628130963d-12) + +(my-assert + (+ -3.885093055726793d-21 -8.523534862249969d-11) + -8.523534862638479d-11) + +(my-assert + (+ 1.027951323422187d-21 -7.65508060829868d-11) + -7.655080608195885d-11) + +(my-assert + (+ -9.83813940552434d-21 -5.048380063082019d-11) + -5.0483800640658324d-11) + +(my-assert + (+ -7.640856498925806d-21 -5.743808556015994d19) + -5.743808556015994d19) + +(my-assert + (+ 8.053891045717591d-21 4.0840032650134725d19) + 4.0840032650134725d19) + +(my-assert + (+ -4.794782783871528d-21 -3.431216587740782d18) + -3.431216587740782d18) + +(my-assert + (+ 1.860870988390988d-21 -3.757945694933625d19) + -3.757945694933625d19) + +(my-assert + (+ 5.445498222566789d-21 7.575823566817991d19) + 7.575823566817991d19) + +(my-assert + (+ 2.631896745307223d-21 4.906449817201212d19) + 4.906449817201212d19) + +(my-assert + (+ -6.61689881073516d-21 5.357007670385275d-21) + -1.2598911403498852d-21) + +(my-assert + (+ 3.0173001109587537d-21 5.2947222461350496d-21) + 8.312022357093803d-21) + +(my-assert + (+ -8.792518441030627d-21 -1.0516787854168774d-21) + -9.844197226447504d-21) + +(my-assert + (+ 7.349451992884509d-21 -8.427997362671486d-21) + -1.0785453697869767d-21) + +(my-assert + (+ -7.881179611953633d-21 3.2080446524364824d-21) + -4.6731349595171506d-21) + +(my-assert + (+ -9.614117725927607d-21 -5.35667712698602d-21) + -1.4970794852913628d-20) + +;; ---- Test von - --- + +(my-assert + (- -0.011326914400453525d0 -0.6668141757661364d0) + 0.6554872613656829d0) + +(my-assert + (- -0.46185382764946437d0 0.7488210697846337d0) + -1.2106748974340982d0) + +(my-assert + (- -0.35834120541234993d0 -0.30919976341834987d0) + -0.04914144199400006d0) + +(my-assert + (- 0.44705025064976966d0 -0.9277893553610955d0) + 1.3748396060108652d0) + +(my-assert + (- -0.47647537517067917d0 0.29158058381073604d0) + -0.7680559589814152d0) + +(my-assert + (- -0.021697999002707746d0 0.1779871773524142d0) + -0.19968517635512195d0) + +(my-assert + (- 0.4179484378019861d0 9.9990307469939d9) + -9.999030746575953d9) + +(my-assert + (- -0.7475415524823718d0 1.3993312799214797d9) + -1.3993312806690214d9) + +(my-assert + (- 0.2519442433861928d0 -6.699632771871848d9) + 6.699632772123793d9) + +(my-assert + (- -0.5124988631497671d0 2.7959244812290273d9) + -2.795924481741526d9) + +(my-assert + (- -0.6870193827604301d0 4.851102442573468d9) + -4.851102443260488d9) + +(my-assert + (- 0.7609656780357723d0 7.481252865855436d8) + -7.481252858245779d8) + +(my-assert + (- -0.6301276042170191d0 -7.099314875214215d-11) + -0.630127604146026d0) + +(my-assert + (- -0.4139053484357884d0 -2.897413526398709d-11) + -0.41390534840681426d0) + +(my-assert + (- -0.6944623060197281d0 -3.291569879873739d-11) + -0.6944623059868125d0) + +(my-assert + (- -0.2057822500703933d0 3.6505182026159854d-11) + -0.2057822501068985d0) + +(my-assert + (- -0.8792706674467908d0 8.094527736950817d-11) + -0.8792706675277361d0) + +(my-assert + (- -0.6888184243601332d0 9.127622796988807d-11) + -0.6888184244514094d0) + +(my-assert + (- -0.980711030497252d0 8.752272461345245d19) + -8.752272461345245d19) + +(my-assert + (- 0.8035082489836539d0 -3.903355151264917d19) + 3.903355151264917d19) + +(my-assert + (- -0.7537841372394811d0 -5.879942447417834d19) + 5.879942447417834d19) + +(my-assert + (- -0.6877475951546845d0 -2.3972266191169642d19) + 2.3972266191169642d19) + +(my-assert + (- -0.43128282112433525d0 -5.422824998003439d19) + 5.422824998003439d19) + +(my-assert + (- 0.29538116818276694d0 1.1291858990580939d19) + -1.1291858990580939d19) + +(my-assert + (- 0.9166687388673976d0 6.395175407123937d-21) + 0.9166687388673976d0) + +(my-assert + (- 0.41840538498193025d0 -2.6655662412599155d-21) + 0.41840538498193025d0) + +(my-assert + (- -0.8036940092501853d0 6.7473779576832565d-21) + -0.8036940092501853d0) + +(my-assert + (- 0.8555054025209989d0 -7.939970418096797d-21) + 0.8555054025209989d0) + +(my-assert + (- 0.3365495704567003d0 8.694519827555395d-21) + 0.3365495704567003d0) + +(my-assert + (- -0.7430322011471231d0 7.430332379292914d-22) + -0.7430322011471231d0) + +(my-assert + (- 5.102372414731216d9 -0.5073635765350494d0) + 5.10237241523858d9) + +(my-assert + (- 4.629827365822252d9 0.6534380055543355d0) + 4.629827365168815d9) + +(my-assert + (- 7.218192507117569d9 0.9781542046565127d0) + 7.218192506139415d9) + +(my-assert + (- 6.595760326622413d8 0.7339510561932947d0) + 6.595760319282902d8) + +(my-assert + (- 7.191166637703489d9 0.80792475493853d0) + 7.191166636895564d9) + +(my-assert + (- -7.95531405213956d9 0.5353636841430115d0) + -7.955314052674924d9) + +(my-assert + (- 5.438904545553836d8 6.533536518165114d9) + -5.989646063609731d9) + +(my-assert + (- -7.389650313101625d8 -9.983943153365381d9) + 9.244978122055218d9) + +(my-assert + (- 8.364404619492165d9 -7.600563055115287d9) + 1.5964967674607452d10) + +(my-assert + (- 2.070813748323649d9 6.421052769114957d9) + -4.350239020791307d9) + +(my-assert + (- -2.8555256820439434d9 -3.4077342921686625d8) + -2.514752252827077d9) + +(my-assert + (- 9.147878229420991d8 8.439982790150545d9) + -7.5251949672084465d9) + +(my-assert + (- -4.315772980070098d9 -6.48869466068404d-11) + -4.315772980070098d9) + +(my-assert + (- -3.5186299785635023d9 3.990046539849716d-11) + -3.5186299785635023d9) + +(my-assert + (- 2.5645532837267537d9 8.566645694205622d-13) + 2.5645532837267537d9) + +(my-assert + (- 6.145110896031829d9 -9.242734002954773d-11) + 6.145110896031829d9) + +(my-assert + (- -6.6836855975624d9 9.117930361283473d-11) + -6.6836855975624d9) + +(my-assert + (- -1.7472828462085754d8 -5.125838712019503d-11) + -1.7472828462085754d8) + +(my-assert + (- 9.05675399397055d9 9.086705650502484d19) + -9.08670564959681d19) + +(my-assert + (- -5.834806594586836d9 9.981576053842906d19) + -9.981576054426386d19) + +(my-assert + (- 3.047010922754272d9 1.1715352070471352d19) + -1.1715352067424342d19) + +(my-assert + (- 7.294295638574767d9 2.845702947515113d19) + -2.8457029467856835d19) + +(my-assert + (- 8.264143132493019d9 -1.6322956072452289d19) + 1.6322956080716431d19) + +(my-assert + (- -9.597823287256088d9 3.954126758718671d19) + -3.954126759678453d19) + +(my-assert + (- 3.229389511771705d9 -4.329831377266493d-21) + 3.229389511771705d9) + +(my-assert + (- 6.897089200279753d9 2.4428208790287663d-21) + 6.897089200279753d9) + +(my-assert + (- 2.3579775300187545d9 4.729400988996349d-21) + 2.3579775300187545d9) + +(my-assert + (- 1.6718929117460046d9 5.8162277016717065d-21) + 1.6718929117460046d9) + +(my-assert + (- 2.537177500868296d9 1.4856605280697543d-21) + 2.537177500868296d9) + +(my-assert + (- 6.117674696930935d9 -1.6187214719634357d-21) + 6.117674696930935d9) + +(my-assert + (- 4.1877888304549216d-11 -0.06920550501017497d0) + 0.06920550505205286d0) + +(my-assert + (- 9.61054846124015d-11 0.885309193732889d0) + -0.8853091936367835d0) + +(my-assert + (- 2.5559085051828467d-11 -0.8112181469812297d0) + 0.8112181470067888d0) + +(my-assert + (- -1.4549570208293283d-12 -0.5049325945871657d0) + 0.5049325945857107d0) + +(my-assert + (- -7.091628047158497d-11 0.61946884965934d0) + -0.6194688497302563d0) + +(my-assert + (- 2.877466355456826d-11 0.4496491857374d0) + -0.44964918570862533d0) + +(my-assert + (- 1.3041612488449928d-12 5.408018587130755d9) + -5.408018587130755d9) + +(my-assert + (- -5.379752339715717d-11 -4.009594691514288d9) + 4.009594691514288d9) + +(my-assert + (- 7.023042501342336d-12 -3.4153434285746374d9) + 3.4153434285746374d9) + +(my-assert + (- 6.968174934871611d-11 4.713087404332662d9) + -4.713087404332662d9) + +(my-assert + (- -5.153562653896506d-11 -8.44732228013254d8) + 8.44732228013254d8) + +(my-assert + (- -8.424177457818745d-11 1.6817117809824567d9) + -1.6817117809824567d9) + +(my-assert + (- 3.374755984316538d-11 8.893678266883364d-11) + -5.5189222825668264d-11) + +(my-assert + (- -8.684123447823306d-11 -7.888825869147879d-11) + -7.952975786754267d-12) + +(my-assert + (- 7.788477523205632d-11 1.741674745286914d-11) + 6.046802777918718d-11) + +(my-assert + (- 6.546622477606044d-11 -4.7719651007530584d-11) + 1.1318587578359101d-10) + +(my-assert + (- -1.8595152377503265d-11 5.7288738553553045d-11) + -7.588389093105631d-11) + +(my-assert + (- -8.184033550427558d-11 -8.834399228929296d-11) + 6.503656785017376d-12) + +(my-assert + (- 5.749469292140762d-11 7.493129199779113d19) + -7.493129199779113d19) + +(my-assert + (- -5.2285095120702066d-11 -2.0611179974216552d19) + 2.0611179974216552d19) + +(my-assert + (- -8.84727820032067d-11 4.7423077384022024d19) + -4.7423077384022024d19) + +(my-assert + (- 3.437676989338625d-11 -3.5368755480277647d19) + 3.5368755480277647d19) + +(my-assert + (- 2.2665031619145437d-11 -6.072845659234921d19) + 6.072845659234921d19) + +(my-assert + (- -8.429070146313393d-11 5.134329153614969d18) + -5.134329153614969d18) + +(my-assert + (- -9.009531819191212d-11 2.301790665456671d-22) + -9.00953181921423d-11) + +(my-assert + (- -2.706942469371907d-11 9.282350542107287d-21) + -2.706942470300142d-11) + +(my-assert + (- 5.358266626996117d-11 -4.409057695582885d-22) + 5.358266627040208d-11) + +(my-assert + (- -7.189537285608088d-11 9.569273217393917d-21) + -7.189537286565016d-11) + +(my-assert + (- -4.160295905335358d-11 5.930867524794025d-21) + -4.160295905928445d-11) + +(my-assert + (- 6.7922062777334035d-12 -7.747524338474154d-22) + 6.792206278508156d-12) + +(my-assert + (- -9.038821102045805d19 0.04779131019959271d0) + -9.038821102045805d19) + +(my-assert + (- 2.2020595055495963d19 -0.424631558292516d0) + 2.2020595055495963d19) + +(my-assert + (- -8.164003027214308d19 0.6832198147365239d0) + -8.164003027214308d19) + +(my-assert + (- -3.878233560364984d19 -0.28756619113600546d0) + -3.878233560364984d19) + +(my-assert + (- 7.0829003521450525d19 -0.6071548125948544d0) + 7.0829003521450525d19) + +(my-assert + (- 5.968540808784698d19 0.7674294173432648d0) + 5.968540808784698d19) + +(my-assert + (- -2.2143621795153547d19 -2.443529365769125d9) + -2.2143621792710017d19) + +(my-assert + (- -9.77092538926342d18 5.903189771537687d8) + -9.77092538985374d18) + +(my-assert + (- 9.974714452399537d19 -6.980456691485629d9) + 9.974714453097582d19) + +(my-assert + (- 1.7428950527159094d18 3.68843657888816d9) + 1.742895049027473d18) + +(my-assert + (- -1.1094381875350845d19 -7.157723640671709d9) + -1.1094381868193122d19) + +(my-assert + (- -3.638795590369631d19 6.9246542750294075d9) + -3.6387955910620963d19) + +(my-assert + (- -5.66543282261991d19 -5.1005028153082024d-11) + -5.66543282261991d19) + +(my-assert + (- -3.901527864456216d19 -1.064153465992923d-12) + -3.901527864456216d19) + +(my-assert + (- 1.1477489418879848d19 3.327888063907735d-11) + 1.1477489418879848d19) + +(my-assert + (- 3.508978072054437d19 9.238453417997638d-11) + 3.508978072054437d19) + +(my-assert + (- -4.7642024461416964d19 -4.758309941438892d-11) + -4.7642024461416964d19) + +(my-assert + (- -8.307715835429606d19 3.313910202186439d-11) + -8.307715835429606d19) + +(my-assert + (- 2.704675010192592d18 -2.6840207147078365d19) + 2.954488215727096d19) + +(my-assert + (- -9.860969100714668d18 -4.719594638795429d19) + 3.7334977287239614d19) + +(my-assert + (- 7.87799781828944d18 -6.657221298850535d19) + 7.44502108067948d19) + +(my-assert + (- -3.3937781740759863d19 4.783805995045389d19) + -8.177584169121376d19) + +(my-assert + (- -1.0747572720102216d19 -1.7144708598072445d19) + 6.397135877970229d18) + +(my-assert + (- 1.3938845733158445d19 5.604369854609131d19) + -4.210485281293287d19) + +(my-assert + (- 6.0938348303695315d19 1.1005522580049531d-21) + 6.0938348303695315d19) + +(my-assert + (- -2.4870844028694925d19 1.5391650322730598d-22) + -2.4870844028694925d19) + +(my-assert + (- 7.323118607079343d19 6.637280375859432d-21) + 7.323118607079343d19) + +(my-assert + (- -4.181201584825501d19 4.768935182006663d-21) + -4.181201584825501d19) + +(my-assert + (- 4.1225910279381205d19 6.117191687463543d-21) + 4.1225910279381205d19) + +(my-assert + (- 6.438313875980151d17 -1.4883489002691529d-21) + 6.438313875980151d17) + +(my-assert + (- -4.573961206963222d-21 0.3586300020381973d0) + -0.3586300020381973d0) + +(my-assert + (- 7.74206782371325d-22 0.23168389210368656d0) + -0.23168389210368656d0) + +(my-assert + (- 8.572446613640605d-21 0.6114581963443891d0) + -0.6114581963443891d0) + +(my-assert + (- -8.539467934859551d-21 0.33474735899049d0) + -0.33474735899049d0) + +(my-assert + (- -5.55811309570968d-21 -0.9637216018651454d0) + 0.9637216018651454d0) + +(my-assert + (- -6.705839413964189d-21 0.3787619614522374d0) + -0.3787619614522374d0) + +(my-assert + (- 1.338539206480238d-22 6.683968625235106d9) + -6.683968625235106d9) + +(my-assert + (- -9.64078167549023d-21 3.291420859310843d9) + -3.291420859310843d9) + +(my-assert + (- -9.26536204591093d-22 2.9839295142529476d8) + -2.9839295142529476d8) + +(my-assert + (- -3.647737608953592d-21 6.115300020921433d8) + -6.115300020921433d8) + +(my-assert + (- 1.4069763806331204d-21 -1.183109060480878d9) + 1.183109060480878d9) + +(my-assert + (- -6.0037865798761924d-21 -7.442246743849378d9) + 7.442246743849378d9) + +(my-assert + (- -5.994118986299138d-21 -9.091558282012836d-11) + 9.091558281413425d-11) + +(my-assert + (- 6.969393585974241d-21 3.435352867093995d-11) + -3.435352866397056d-11) + +(my-assert + (- -6.278554484817533d-22 -4.7211920270841604d-11) + 4.721192027021375d-11) + +(my-assert + (- -8.603262886304741d-21 1.7296517702077242d-11) + -1.7296517710680505d-11) + +(my-assert + (- 4.104502790901735d-21 -4.8473213720301105d-11) + 4.847321372440561d-11) + +(my-assert + (- -4.449725859444968d-21 -8.944265568403936d-11) + 8.944265567958964d-11) + +(my-assert + (- 4.828216540804827d-21 -1.1712152029346877d19) + 1.1712152029346877d19) + +(my-assert + (- -5.65034940464881d-21 -9.445303840982011d19) + 9.445303840982011d19) + +(my-assert + (- -7.24107519738777d-21 2.340578690102746d19) + -2.340578690102746d19) + +(my-assert + (- 1.7659593956231534d-21 -8.048768257390671d18) + 8.048768257390671d18) + +(my-assert + (- -3.0538518255248124d-21 8.834631867521575d19) + -8.834631867521575d19) + +(my-assert + (- 8.57952908388053d-21 -5.730742870111307d19) + 5.730742870111307d19) + +(my-assert + (- -4.5090103564928485d-21 1.8907114777916313d-21) + -6.399721834284479d-21) + +(my-assert + (- -3.8487625143236447d-22 5.354282198078924d-21) + -5.739158449511288d-21) + +(my-assert + (- 2.6660110440404615d-22 3.833744224501756d-22) + -1.1677331804612944d-22) + +(my-assert + (- -7.503762004261027d-22 -9.623906576475644d-21) + 8.873530376049542d-21) + +(my-assert + (- -9.113431042260725d-21 -3.5516521546085545d-21) + -5.56177888765217d-21) + +(my-assert + (- -3.4813735333296525d-21 -2.6602650182385188d-21) + -8.211085150911337d-22) + +;; ---- Test von * --- + +(my-assert + (* -0.2554913394465045d0 0.27042187315261135d0) + -0.0690904465873934d0) + +(my-assert + (* -0.4489211233229662d0 -0.42892136850270857d0) + 0.19255186256545986d0) + +(my-assert + (* -0.44586465919973783d0 -0.15168042462027043d0) + 0.0676289408305884d0) + +(my-assert + (* 0.5509395670465355d0 0.3577558280766836d0) + 0.19710184102894285d0) + +(my-assert + (* -0.42780066410606965d0 0.22704747885906007d0) + -0.0971310622395147d0) + +(my-assert + (* 0.20955388816500042d0 0.605628751935113d0) + 0.12691185975251945d0) + +(my-assert + (* 0.9993471610818964d0 -4.363771855901198d9) + -4.360923015803941d9) + +(my-assert + (* 0.10502219375257282d0 3.425205053451057d9) + 3.5972254876582843d8) + +(my-assert + (* 0.7768651149081368d0 1.666066330143864d9) + 1.2943088110117908d9) + +(my-assert + (* -0.6438389801759042d0 2.8922130868526487d9) + -1.8621195242906134d9) + +(my-assert + (* -0.7427680566504474d0 6.763974500466173d9) + -5.02406419494444d9) + +(my-assert + (* -0.8563035843259611d0 2.9100478627456827d9) + -2.4918844154292307d9) + +(my-assert + (* 0.6219502737119671d0 2.8868752190811842d-11) + 1.7954928326798375d-11) + +(my-assert + (* 0.6767479505813657d0 2.9324524289075574d-11) + 1.9845311714405376d-11) + +(my-assert + (* 0.7944531541461581d0 8.282076647859848d-11) + 6.579721915772496d-11) + +(my-assert + (* -0.4662914070981966d0 -6.921260263903422d-11) + 3.227324187348362d-11) + +(my-assert + (* 0.037804762510578516d0 -3.044514833184461d-11) + -1.1509716022847211d-12) + +(my-assert + (* -0.5364168049485208d0 -3.695280705974925d-11) + 1.9822106696869836d-11) + +(my-assert + (* 0.10343751426551051d0 4.8902635121181385d19) + 5.058367017968255d18) + +(my-assert + (* -0.45511004829813784d0 1.8210069906740634d19) + -8.287585794769196d18) + +(my-assert + (* -0.9675158737162977d0 8.097401718869682d19) + -7.83436469886405d19) + +(my-assert + (* -0.06573561186185628d0 2.6049125586869125d19) + -1.712355208919178d18) + +(my-assert + (* -0.5574365795036731d0 -8.822383181882661d19) + 4.917919103979403d19) + +(my-assert + (* -0.4222667103024276d0 -1.8561723355961213d19) + 7.837997859065477d18) + +(my-assert + (* -0.8412207478192143d0 2.3416069046402696d-22) + -1.9698083114201234d-22) + +(my-assert + (* 0.24291385591230452d0 -9.448120185342916d-21) + -2.295079305344525d-21) + +(my-assert + (* -0.37792600430678414d0 -2.3929024368177364d-21) + 9.043400566424941d-22) + +(my-assert + (* -0.007648867433060369d0 -5.3162210182098465d-21) + 4.066306981313633d-23) + +(my-assert + (* -0.7631807323096114d0 -4.534410248041209d-21) + 3.4605745336922964d-21) + +(my-assert + (* 0.4735366300649959d0 -1.3895270471326203d-21) + -6.579919552833457d-22) + +(my-assert + (* -8.64834403600587d9 -0.14057280586223464d0) + 1.215721987203268d9) + +(my-assert + (* -1.5525713051163936d9 0.10621224657238759d0) + -1.64902086280236d8) + +(my-assert + (* 3.297132746298694d9 0.05318660311813239d0) + 1.7536329080518654d8) + +(my-assert + (* 2.1659831568875275d9 0.11704159596099262d0) + 2.5351012550674528d8) + +(my-assert + (* -5.533403510176525d9 0.37778599060251605d0) + -2.0904423264954782d9) + +(my-assert + (* -2.4217306331294374d9 0.6051350227557695d0) + -1.465474021787126d9) + +(my-assert + (* 1.4048311850866513d9 -4.304799039580996d9) + -6.047515936334449d18) + +(my-assert + (* -5.070278162013437d9 -9.116233758795675d9) + 4.622184094703138d19) + +(my-assert + (* 8.452801605894673d9 -9.002885976919611d9) + -7.609960904339272d19) + +(my-assert + (* 6.352601599408395d9 -4.484034289922495d9) + -2.848528340196373d19) + +(my-assert + (* -6.565407710101401d8 -6.718825369609182d9) + 4.4111827884457016d18) + +(my-assert + (* -9.37193973536698d9 9.577576231327314d9) + -8.976046725088279d19) + +(my-assert + (* -1.7766859308675253d9 -4.079350537765101d-11) + 0.0724772470752413d0) + +(my-assert + (* 2.3810136983742104d9 9.195156930614704d-11) + 0.2189379461049417d0) + +(my-assert + (* -3.313966320976337d9 -3.44704749912067d-11) + 0.11423399318891611d0) + +(my-assert + (* 6.598963960681895d9 -2.4298605961767928d-11) + -0.1603456250365168d0) + +(my-assert + (* 7.908258993705348d9 1.528909719631646d-11) + 0.12091014040840486d0) + +(my-assert + (* -5.906667889594469d9 5.917852809041966d-11) + -0.3495479116251461d0) + +(my-assert + (* 4.86261281419926d9 -2.3925611132123714d19) + -1.1634098327861323d29) + +(my-assert + (* -9.753392818607462d9 -2.5653634777279775d18) + 2.502099772078992d28) + +(my-assert + (* 1.5861252889272392d9 5.12939252547053d19) + 8.135859201483165d28) + +(my-assert + (* -8.422142961023593d8 1.0428099441045047d19) + -8.782694430425161d27) + +(my-assert + (* -3.109042783121446d9 -4.138252722536039d19) + 1.286600476173335d29) + +(my-assert + (* -6.459303282089468d8 1.8408981660472957d19) + -1.189091956594178d28) + +(my-assert + (* -1.432764110232635d9 8.98766033001457d-21) + -1.2877197155806476d-11) + +(my-assert + (* 8.539623949953406d9 -3.498784805440049d-21) + -2.987830652026891d-11) + +(my-assert + (* 7.336784327799637d9 -1.048985206018761d-21) + -7.696178219612119d-12) + +(my-assert + (* -4.320357143553698d9 2.591531476439043d-21) + -1.119634152697768d-11) + +(my-assert + (* -9.374098076239548d9 5.5773248420603045d-21) + -5.228239007252054d-11) + +(my-assert + (* 9.118926580475056d9 -1.379170270330765d-21) + -1.2576552437120181d-11) + +(my-assert + (* 8.145792307872788d-11 -0.06511382435429458d0) + -5.304036895613926d-12) + +(my-assert + (* -6.1928426627437d-11 0.2526275616632321d0) + -1.5644827416529785d-11) + +(my-assert + (* -8.555119338859813d-11 -0.8366318482083728d0) + 7.157485304113478d-11) + +(my-assert + (* 8.243060442429263d-12 0.3939656708074719d0) + 3.2474828367081808d-12) + +(my-assert + (* 8.600529286105945d-11 -0.891441509265547d0) + -7.666868807288822d-11) + +(my-assert + (* -7.531046724969747d-11 0.24398797995196886d0) + -1.8374848773492595d-11) + +(my-assert + (* -3.7666526619188126d-12 4.659322150343885d9) + -0.017550048180330083d0) + +(my-assert + (* 3.032501107241211d-11 -9.592046453776636d9) + -0.2908789149178678d0) + +(my-assert + (* 7.311626957349528d-11 -9.061108567148174d9) + -0.6625144566303135d0) + +(my-assert + (* 4.898078204161461d-11 8.88014689134599d9) + 0.4349565393825394d0) + +(my-assert + (* 1.278207138618518d-11 -4.279966992086118d9) + -0.05470684362336102d0) + +(my-assert + (* -8.538580654966055d-11 -5.191059833953482d8) + 0.0443242830769665d0) + +(my-assert + (* 4.0761422500127225d-11 1.527607426117321d-11) + 6.226745171030001d-22) + +(my-assert + (* -9.186363051001198d-11 8.557763803549676d-11) + -7.861472520412421d-21) + +(my-assert + (* -9.89183505930065d-11 9.717968160611499d-11) + -9.612853815630427d-21) + +(my-assert + (* 7.440627873114725d-12 -4.535521332601712d-11) + -3.374712644646274d-22) + +(my-assert + (* 8.701410920357686d-11 -7.032883383151379d-12) + -6.119600827175551d-22) + +(my-assert + (* 9.866226673114161d-11 -2.814669610817353d-11) + -2.777016839025002d-21) + +(my-assert + (* 5.192240545105114d-11 -3.366056660574579d19) + -1.747737587015645d9) + +(my-assert + (* -1.372355669576939d-11 -4.819955130360066d19) + 6.61469275025609d8) + +(my-assert + (* 3.637511103766519d-11 -4.071776382810416d19) + -1.4811131804527159d9) + +(my-assert + (* 7.446388208685151d-13 2.7760294268649034d19) + 2.0671392791169815d7) + +(my-assert + (* 6.267855179410938d-11 7.471751480940298d19) + 4.683185621908299d9) + +(my-assert + (* -4.336562006766369d-11 8.143188451558233d19) + -3.5313441652966094d9) + +(my-assert + (* -1.0432655006975122d-11 -9.379512413340694d-21) + 9.785321714202411d-32) + +(my-assert + (* -8.167646898574611d-11 -5.810795749825724d-21) + 4.746052788431461d-31) + +(my-assert + (* -4.33805459341994d-11 -2.4289860591796017d-21) + 1.053707413137707d-31) + +(my-assert + (* -1.384613082275421d-11 2.2174009100764947d-21) + -3.070242308741339d-32) + +(my-assert + (* -4.910905591314494d-11 -5.456657623752349d-21) + 2.679713043437427d-31) + +(my-assert + (* 1.3653011366548008d-11 -3.925911962906968d-21) + -5.360052065363564d-32) + +(my-assert + (* 7.641468950470222d19 0.9034599537348024d0) + 6.903761184457755d19) + +(my-assert + (* 5.146778093125584d19 -0.2791459460022878d0) + -1.436702239669392d19) + +(my-assert + (* -8.874303077863696d19 -0.23153988023519345d0) + 2.054755071819369d19) + +(my-assert + (* 7.10798162637783d19 -0.4719034863212067d0) + -3.354281310194779d19) + +(my-assert + (* -9.820386602197546d19 0.03346146041258036d0) + -3.286044775256677d18) + +(my-assert + (* -5.210458089116161d19 0.11173798093222442d0) + -5.822060666098161d18) + +(my-assert + (* 3.257626718953688d18 -6.150510855712356d9) + -2.0036068498783283d28) + +(my-assert + (* -7.755105754004988d19 5.514896832715505d9) + -4.27686081601359d29) + +(my-assert + (* 2.426235084788384d19 8.685431434428486d9) + 2.1072898472734294d29) + +(my-assert + (* -2.847383850475709d19 -2.412830829567453d9) + 6.870255538040273d28) + +(my-assert + (* 1.4664659669727164d19 -4.8673539253155d9) + -7.1378088806862425d28) + +(my-assert + (* -4.24770317054668d19 1.3102543269150825d9) + -5.5655714586597015d28) + +(my-assert + (* 2.17116835964837d19 -3.654789326884115d-11) + -7.935162947711353d8) + +(my-assert + (* -1.8125809977916906d17 -5.944782899600832d-11) + 1.0775400519813456d7) + +(my-assert + (* -7.915462827540546d19 9.762153025588201d-11) + -7.727195939080587d9) + +(my-assert + (* -4.360953588949649d19 -7.152431005584812d-11) + 3.119141966351983d9) + +(my-assert + (* 3.550776271395866d19 -6.387656982922894d-11) + -2.268114084477872d9) + +(my-assert + (* -8.278954580496595d19 -7.359178231519021d-11) + 6.092630232852524d9) + +(my-assert + (* -5.5022682113038156d19 -8.979630229039327d19) + 4.940833395850589d39) + +(my-assert + (* 1.1716230943203277d19 5.5764415854118265d19) + 6.533487745596758d38) + +(my-assert + (* 7.462799608352103d19 6.061883497941003d19) + 4.523862179431019d39) + +(my-assert + (* -3.2160334983646097d19 -3.8817785710003675d19) + 1.2483929917571087d39) + +(my-assert + (* 5.868090263060238d19 -8.37300331667736d19) + -4.91335392351655d39) + +(my-assert + (* -7.3652924769962656d19 9.725738480757314d19) + -7.163290846555493d39) + +(my-assert + (* -6.447063647969567d19 4.0587529685661844d-21) + -0.2616703871973161d0) + +(my-assert + (* -3.1999317568381926d17 3.015031281949113d-21) + -9.647894346969533d-4) + +(my-assert + (* -1.5005852398726605d19 5.391316601974659d-21) + -0.080901301164036d0) + +(my-assert + (* 1.0084552719733576d19 2.78150956101201d-21) + 0.02805027980846861d0) + +(my-assert + (* -7.171404412051077d19 1.4733392992015492d-21) + -0.10565911950742231d0) + +(my-assert + (* -5.909802783283228d19 5.356071274587122d-21) + -0.31653324926018317d0) + +(my-assert + (* 8.272641144282955d-22 -0.16191056182923802d0) + -1.3394279754825238d-22) + +(my-assert + (* 8.410471541398583d-21 -0.43256058128353736d0) + -3.63803845881602d-21) + +(my-assert + (* -7.887238384137063d-22 0.5589746137044918d0) + -4.408766028968254d-22) + +(my-assert + (* 4.778995446616728d-21 0.21608373898977795d0) + 1.0326632047200663d-21) + +(my-assert + (* 3.992449163872154d-21 0.9593422165456676d0) + 3.830125030315009d-21) + +(my-assert + (* -9.700320218813958d-21 -0.42620535269852766d0) + 4.134328400148262d-21) + +(my-assert + (* -1.7901566262876555d-21 9.461674014776534d8) + -1.6937878433325936d-12) + +(my-assert + (* 1.0928019952544443d-22 8.279199780524873d9) + 9.047526039267738d-13) + +(my-assert + (* 9.942869097320962d-21 9.523169242022762d9) + 9.468762516506561d-11) + +(my-assert + (* -2.7432601692209267d-21 -4.922145522647528d9) + 1.3502725759388083d-11) + +(my-assert + (* -5.97929682563092d-21 -6.147792689359443d8) + 3.6759477312123895d-12) + +(my-assert + (* -1.3564305221188254d-21 1.0862842413758955d9) + -1.473469100698958d-12) + +(my-assert + (* -5.446806293721964d-21 -1.5358504316888942d-11) + 8.365479797538665d-32) + +(my-assert + (* -1.0222776562632463d-21 -1.9781477525280056d-11) + 2.0222162481967376d-32) + +(my-assert + (* 8.192540157543917d-21 3.3215076993103644d-11) + 2.7211585210191467d-31) + +(my-assert + (* 9.685592607330157d-21 6.034805605641166d-11) + 5.8450668560672665d-31) + +(my-assert + (* 6.671870463340688d-21 -9.07657686679269d-11) + -6.055774510579552d-31) + +(my-assert + (* -1.109409648670322d-21 -4.7905821901849965d-11) + 5.314718104539439d-32) + +(my-assert + (* -3.9052432481663676d-22 2.0306112771345453d19) + -0.007930030979680168d0) + +(my-assert + (* 8.596834841113507d-21 -9.453548987989818d19) + -0.8127059931212419d0) + +(my-assert + (* 3.946325780779758d-21 -9.084484011754447d19) + -0.35850333460668093d0) + +(my-assert + (* 5.3518824877647604d-21 -6.814116447592617d19) + -0.36468350485460743d0) + +(my-assert + (* -7.456278485417833d-22 9.61914445493285d19) + -0.07172301984744206d0) + +(my-assert + (* -5.0781537010216826d-21 9.216915512986622d19) + -0.4680491362427718d0) + +(my-assert + (* 3.2906792172396555d-22 4.571445785546992d-21) + 1.50431616392373d-42) + +(my-assert + (* 5.39814714322422d-21 6.687033308557664d-21) + 3.6097589751235757d-41) + +(my-assert + (* 4.3506183844841724d-21 7.266196706225928d-21) + 3.1612448975384865d-41) + +(my-assert + (* 6.910763289107986d-21 3.910584203890238d-21) + 2.702512175521024d-41) + +(my-assert + (* -4.6131515924393325d-21 5.228174479773633d-21) + -2.411836142691841d-41) + +(my-assert + (* -2.1886866436065787d-21 6.29322016055891d-22) + -1.3773886910690934d-42) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.6173351962722496d0 -0.11820538775792844d0)) + (-6 -0.09189713027532098d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.17517225806171177d0 0.1118228341753209d0)) + (-2 0.04847341028893004d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9387909021047899d0 -0.16826318310698907d0)) + (5 -0.09747498656984459d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.8036728904567848d0 0.6774308237913269d0)) + (1 0.1262420666654578d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.6882568422881421d0 0.3302150266778784d0)) + (2 0.02782678893238538d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.3618917435888378d0 0.5454396894763598d0)) + (0 0.3618917435888378d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.478470818234076d0 9.035797971846054d9)) + (-1 9.035797971367584d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.6423779722022549d0 2.0589504447793393d9)) + (0 0.6423779722022549d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.21698095744051404d0 1.570908384361449d9)) + (0 0.21698095744051404d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.24033995915823747d0 6.968395233824382d9)) + (0 0.24033995915823747d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.8531247643149816d0 -5.299783511441018d9)) + (0 -0.8531247643149817d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.5134978162655872d0 2.297671112225289d9)) + (-1 2.297671111711791d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.6192405432591311d0 5.4403538407469436d-11)) + (11382357864 3.744539199218032d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.20340731452742233d0 5.44351944436815d-12)) + (-37366875715 2.4681729170135434d-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.29394735220898527d0 -3.6328318262890404d-12)) + (80914109505 -3.3847154436219604d-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.8359336184185098d0 6.064791537508077d-11)) + (-13783385847 1.2432123964511977d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9762544843227843d0 2.2086465633336306d-11)) + (-44201480696 1.1997821346734454d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.2919696169517234d0 6.922295436251983d-11)) + (-4217815025 3.3402028237741715d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.9452118035872986d0 -1.1093667270485797d19)) + (-1 -1.1093667270485797d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.3379784391207531d0 -3.0106029588222304d19)) + (-1 -3.0106029588222304d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.3907483945162724d0 -9.823409070968835d19)) + (-1 -9.823409070968835d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.4293216868359586d0 5.965415751655242d19)) + (-1 5.965415751655242d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.13727607148241305d0 -8.310631671228052d19)) + (-1 -8.310631671228052d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.7478116595122868d0 7.235991436975452d19)) + (-1 7.235991436975452d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9425796643098138d0 -1.7749544068364875d-21)) + (531044437355311857664 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.20835281321620536d0 2.7983277403481253d-21)) + (74456186890490986496 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.5404541167071248d0 9.266841531614177d-22)) + (-583212861537931100160 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.06796825059990208d0 -6.350644782153893d-21)) + (10702574767038046208 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.30647600932087793d0 -9.704243038852408d-21)) + (-31581650221851901952 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.7939481974521416d0 -7.44148349933678d-21)) + (106692193501860495360 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.622471924924206d9 0.3428958732728865d0)) + (7648012499 0.2776496600055352d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.96303133513731d9 -0.6839887200892081d0)) + (-14566075496 -0.09450688719173875d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.438132647041376d8 -0.9350840745499996d0)) + (-1009335193 -0.15301271996267998d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.031281076435459d9 0.8566679205528436d0)) + (-5873082155 0.5244045303768723d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.504293159523993d9 -0.17779074115973026d0)) + (53457750935 -0.058079864158457416d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.593337221858664d8 0.6365106532159245d0)) + (878749977 0.3121177083383602d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.849085830660753d9 5.465582064164139d9)) + (-2 1.0820782976675239d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.254242990207708d9 1.9986128256161973d9)) + (3 2.5840451335911673d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.644949290710447d9 3.677515142398587d9)) + (-3 1.3875961364853137d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.966654669106707d9 3.622741134738514d9)) + (2 2.7211723996296782d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.024110605080818d9 -1.3131548351819434d9)) + (5 -4.583364291711011d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.5982831731090415d8 -4.587607917895467d9)) + (0 -4.5982831731090415d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.779683583609543d9 -8.732134194560264d-11)) + (-77640625218895380480 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.040910010354103d8 -6.386892985922651d-11)) + (-4761172634419539968 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.081490496057175d9 -8.389512916135551d-11)) + (108248125807050637312 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.3391140718625803d9 4.078343101769488d-11)) + (-57354519065541566464 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.740679130260033d9 -4.1307299498162d-11)) + (-235810117064018001920 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.630742761978566d9 -8.36053471494181d-11)) + (-55388117146413842432 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.607827158404311d8 1.9791074337467208d19)) + (0 6.607827158404311d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.5835379695092866d9 -5.599741962857091d19)) + (-1 -5.599741962698737d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.972337740404726d9 -1.4833907125668299d19)) + (0 -9.972337740404726d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.8545208802037845d9 5.460276762513134d19)) + (-1 5.4602767622276825d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.4574292483978963d9 8.177006210253868d19)) + (0 3.4574292483978963d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.94800692720856d9 5.400944544004402d19)) + (-1 5.400944543309601d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.2301147741459103d9 4.352417825189536d-22)) + (5123852680777023531125296857088 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.855798499915275d9 -2.1597757039453335d-21)) + (-1322266240285272897749142994944 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.247757812861889d9 -8.000803060408911d-21)) + (-780891338743010366964468023296 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.41352264607702d8 2.4583479152659926d-21)) + (-342242958933120698647142465536 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.08798064415713d9 -4.6826703076651156d-21)) + (-1940768844921862497464005689344 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.450923950975804d9 -8.516681149015905d-21)) + (287779230910741073293637320704 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.535114995775952d-11 -0.4217447234387455d0)) + (0 -6.535114995775952d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.91351782048677d-13 -0.8578740601420116d0)) + (-1 -0.8578740601413203d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.879448244992307d-11 -0.6016918305263045d0)) + (0 -9.879448244992307d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.820572196574365d-11 -0.8508242256358738d0)) + (-1 -0.8508242255576681d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.4420680878896835d-11 0.6509799475016377d0)) + (-1 0.650979947457217d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.35377304874932d-11 -0.7623592484047194d0)) + (0 -8.35377304874932d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.697219220983554d-11 -2.0199834401398075d9)) + (0 -4.697219220983554d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.027899822164905d-11 -3.0043885624092436d8)) + (-1 -3.0043885624092436d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.473748837497406d-11 -6.081705720880249d8)) + (0 -9.473748837497406d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.257060775257221d-11 4.479345462936419d9)) + (-1 4.479345462936419d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.076402998599221d-11 3.0379052042471523d9)) + (-1 3.0379052042471523d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.2516054170046405d-11 9.075782126517027d9)) + (0 3.2516054170046405d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.77186165285192d-12 -7.011585244893556d-11)) + (-1 -6.234399079608364d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.129939073543463d-11 -4.398862671531905d-11)) + (0 -4.129939073543463d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.986332353670153d-11 4.056354917830567d-11)) + (-2 3.126377481990981d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.358815251785654d-11 3.044610839789864d-11)) + (-3 2.7750172675839383d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.5218538547762808d-11 -4.9239841620755075d-11)) + (0 -1.5218538547762808d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.714719523899548d-11 -3.338962509681127d-11)) + (1 -3.757570142184203d-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.7559900032627426d-11 -7.103620895893612d19)) + (0 -3.7559900032627426d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.442771371655891d-11 3.2650979291930292d19)) + (0 3.442771371655891d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.026236668129701d-11 -7.030175018925641d19)) + (0 -8.026236668129701d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.0245932625540036d-11 9.919022649131396d19)) + (0 4.0245932625540036d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.558019989897738d-11 9.805879474847002d19)) + (0 6.558019989897738d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.950419173616613d-11 7.8967335533488d19)) + (-1 7.8967335533488d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.2555105814142415d-11 -7.367149245343951d-22)) + (57763327980 -5.012024424412273d-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.125466497249949d-11 -9.625683307253578d-21)) + (7402556545 -6.2922712544984485d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.076311292972551d-11 5.7198456178965606d-21)) + (14119806429 1.262169607592943d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.024787982764915d-11 1.5125149703168537d-21)) + (-46444419531 6.648179051963393d-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.3153240875994985d-11 -1.5025822462858028d-21)) + (-15408967419 -1.3907844732195436d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.445189938981536d-11 -1.8886893988697117d-21)) + (-50009228329 -8.218058303553574d-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.982223463756733d19 0.20677548795071854d0)) + (-434394983311440412672 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.6872844858317455d19 0.00946240694180256d0)) + (-2839958693765316083712 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.566658458393646d19 -0.38847162936974444d0)) + (246264018659858710528 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.235085548018657d19 -0.06527446136754045d0)) + (648812025299173376000 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.8443413501845017d19 -0.04996947402848739d0)) + (-569215787335074643968 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.484750058861429d19 -0.2338784192921971d0)) + (191755616975433072640 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.986802109112903d19 5.923385648786668d9)) + (-5042390090 3.561083576852057d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.088567504347222d18 9.070536452627407d9)) + (891740807 8.158341046664973d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.09688480137261d19 -6.508291621550677d9)) + (4758368219 -1.75538588669977d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.226418080435591d19 7.892147197133178d9)) + (5355219530 6.335538696917366d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.4013831972690205d19 -2.4924246236187544d9)) + (-5622570023 -6.556610185422871d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.1838203826708914d19 8.941814127664919d9)) + (6915621700 8.062833976289089d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.916774706038343d18 3.120694095597196d-11)) + (-221642189018039718512504602624 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.435687674071892d19 -3.149833308668829d-11)) + (-2995614926067172775889444274176 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.212546775235241d19 3.239266009361982d-11)) + (-1917887187183768183263136317440 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.749482734068419d19 -5.5235623432819116d-11)) + (-859858627258009608103722483712 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.0587261660909548d19 4.4929685621578874d-11)) + (680780674018761986414328414208 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.141754743467259d19 5.235000122629564d-11)) + (791166121575339566219965497344 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.2481803107227873d19 7.39878580568375d18)) + (-2 2.3157685041396265d18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.5884453212818639d19 -8.336283910718495d19)) + (0 -1.5884453212818639d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.000368279611168d19 -5.031778160332162d19)) + (-1 -3.1409880720993677d17)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.6360612893747024d19 4.7875734964388405d19)) + (-1 1.1515122070641383d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.357251757890727d19 -4.493498319637942d19)) + (-1 -2.136246561747215d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.0747068626287395d19 8.591364094011977d19)) + (0 5.0747068626287395d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.1440483442615423d19 9.668454918695627d-21)) + (2217570813838780736509865871750106972160 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.818664212173065d19 -8.186497379734964d-21)) + (-10772206724212702608743560617665161592832 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.376250633760416d19 -6.382238421048869d-21)) + (11557466435965877316178494055246213414912 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.374244855009332d19 3.864539687646209d-21)) + (-11318928536282082575630148538694692241408 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.578656580690454d19 9.103502086399884d-22)) + (83249902166909342613269419960118328426496 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.759312769216988d19 -9.830658049049094d-21)) + (-5858522125865295462884970652182979280896 0.0d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.091696063135083d-21 0.3220521420236615d0)) + (-1 0.3220521420236615d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.472975994693659d-21 -0.06404310380828848d0)) + (0 -7.472975994693657d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.2994935284804662d-21 0.8294627436562217d0)) + (0 2.2994935284804662d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.098532726052559d-21 -0.5103342535054871d0)) + (0 -6.098532726052559d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.8237727943808d-21 0.20193503990844952d0)) + (-1 0.20193503990844952d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.357065560054238d-21 0.535324456368991d0)) + (-1 0.535324456368991d0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.67862366495009d-23 5.869284875063336d9)) + (0 8.67862366495009d-23)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.913399519946995d-21 4.645302733766437d9)) + (-1 4.645302733766437d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.256033435453117d-21 3.5904533516671333d9)) + (0 6.2560334354531166d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.970558626381476d-21 4.548434922363557d9)) + (-1 4.548434922363557d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.442840440717647d-21 -3.3266294818989463d9)) + (-1 -3.3266294818989463d9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.6732789449833775d-21 5.614289998802058d8)) + (-1 5.614289998802058d8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.136201304639634d-21 -1.152382297069954d-12)) + (-1 -1.1523822899337527d-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.575364316308001d-21 -4.790622052171537d-11)) + (0 -7.575364316308001d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.212759331893804d-21 -6.41398602124991d-11)) + (-1 -6.413986020328634d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.9103188467401064d-21 -5.1860189481412404d-11)) + (0 -1.9103188467401064d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.473075242507236d-21 2.3036197131739102d-11)) + (-1 2.303619712726603d-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.138595152941494d-21 2.9424719822474346d-11)) + (0 5.138595152941494d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.137698996313833d-22 2.2468745456943227d19)) + (-1 2.2468745456943227d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.229848882029144d-21 -3.031606285079872d19)) + (0 -7.229848882029144d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.85451854164106d-21 1.7676693722776926d19)) + (-1 1.7676693722776926d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.372223270507929d-21 -7.439745956384552d19)) + (-1 -7.439745956384552d19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.598138480271164d-21 5.149401801116799d19)) + (0 5.598138480271163d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.285618896860432d-21 6.546424273112694d19)) + (0 9.285618896860432d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.511556502656318d-21 4.2351039143592516d-21)) + (1 3.2764525882970666d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.050106800286075d-21 -1.187392681676287d-21)) + (-6 -1.0742492897716469d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.274671258683056d-21 8.647095729321104d-21)) + (0 4.274671258683056d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.344809600387072d-21 6.305446958850813d-21)) + (1 1.039362641536258d-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.753544125648588d-21 9.227661371269332d-21)) + (1 5.258827543792571d-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.227362780459908d-21 -6.70179577363263d-21)) + (1 -5.255670068272766d-22)) + +;; ---- Test von / --- + +(my-assert + (/ -0.651381628953465d0 -0.9237050214744277d0) + 0.7051835962889135d0) + +(my-assert + (/ 0.5067986732438687d0 0.6260017267692811d0) + 0.8095803119575966d0) + +(my-assert + (/ -0.8399445051045212d0 0.1829250718359493d0) + -4.591740742120902d0) + +(my-assert + (/ -0.5987041550692662d0 -0.4124053212463479d0) + 1.4517372211878756d0) + +(my-assert + (/ 0.5861382519823647d0 -0.7560374696447822d0) + -0.7752767230673855d0) + +(my-assert + (/ -0.012882644582824954d0 -0.4671067448591679d0) + 0.02757965866390787d0) + +(my-assert + (/ -0.7830198970435231d0 2.1690164135025935d9) + -3.610022921767931d-10) + +(my-assert + (/ -0.2339206226652567d0 2.729373380002701d9) + -8.57048817062271d-11) + +(my-assert + (/ -0.2285806315782951d0 -2.602073870582813d9) + 8.784555817667759d-11) + +(my-assert + (/ -0.5298716781559242d0 1.3509547453340487d9) + -3.9222015392151683d-10) + +(my-assert + (/ 0.7287190523338418d0 -8.244205871151566d9) + -8.839166121309548d-11) + +(my-assert + (/ 0.18973054487786212d0 6.557593452200545d9) + 2.893295326415727d-11) + +(my-assert + (/ 0.5084032300982587d0 4.5431682148621014d-11) + 1.119049980221105d10) + +(my-assert + (/ 0.6621212705475221d0 -1.838873437953206d-11) + -3.600689731450519d10) + +(my-assert + (/ -0.4041791750277005d0 7.707875701307648d-11) + -5.243716825365141d9) + +(my-assert + (/ -0.09569063343466655d0 4.789751448902253d-11) + -1.9978204392338054d9) + +(my-assert + (/ -0.6471008513340974d0 1.890250884404079d-11) + -3.4233596009563705d10) + +(my-assert + (/ -0.4301276572683971d0 9.134844738134672d-11) + -4.708647706651978d9) + +(my-assert + (/ -0.5061027989171409d0 4.246468515299164d19) + -1.1918204434902915d-20) + +(my-assert + (/ -0.9601783702217944d0 7.495754288877955d19) + -1.2809629734615065d-20) + +(my-assert + (/ -0.6477754868655262d0 -8.507334914535449d19) + 7.614317449272521d-21) + +(my-assert + (/ 0.1934462826116784d0 3.6173521417193476d19) + 5.347731573618163d-21) + +(my-assert + (/ -0.7794308505212441d0 4.172217291786081d19) + -1.8681453913144062d-20) + +(my-assert + (/ -0.8462346361305484d0 7.378170819620111d19) + -1.1469436759043748d-20) + +(my-assert + (/ 0.9783005897625496d0 6.175045007596078d-21) + 1.584280905740958d20) + +(my-assert + (/ -0.9700832605850568d0 -1.7695051741124812d-21) + 5.482229013948009d20) + +(my-assert + (/ 0.07062591404368701d0 -8.855398515753737d-21) + -7.975464223100028d18) + +(my-assert + (/ 0.4751383409805402d0 -8.1371029771106d-21) + -5.8391585103087485d19) + +(my-assert + (/ -0.5103510786836052d0 8.302178001281015d-21) + -6.14719509271975d19) + +(my-assert + (/ 0.7148807879199733d0 4.338856119331781d-21) + 1.6476250151158982d20) + +(my-assert + (/ 4.180670608983218d9 -0.8621420131862095d0) + -4.849167010818503d9) + +(my-assert + (/ 3.202209376555907d9 0.008113117870009012d0) + 3.9469528581523615d11) + +(my-assert + (/ 7.767843042272955d9 -0.04145956871894663d0) + -1.8735947532235483d11) + +(my-assert + (/ 1.1937839884817846d9 0.45557753834605563d0) + 2.6203749921818776d9) + +(my-assert + (/ -2.4205138097471213d9 -0.3737757916008485d0) + 6.475844247109412d9) + +(my-assert + (/ -7.534066568550288d9 -0.3609372553147958d0) + 2.0873618496321087d10) + +(my-assert + (/ 6.098867840095913d9 3.0464612528039427d9) + 2.0019515542771322d0) + +(my-assert + (/ 4.956687716396978d9 7.035407926465974d9) + 0.704534515724495d0) + +(my-assert + (/ 6.969049109639194d9 -8.115758334653503d9) + -0.8587058438990264d0) + +(my-assert + (/ -8.0699835500126705d9 -1.1896420666819375d9) + 6.783539163608158d0) + +(my-assert + (/ -2.229793060172571d9 -2.658809828346301d9) + 0.8386433043838396d0) + +(my-assert + (/ 3.0672739776038485d9 -7.988270854370873d9) + -0.3839722054398737d0) + +(my-assert + (/ 2.477055391151669d9 -1.3522358047779648d-11) + -1.8318220700851785d20) + +(my-assert + (/ 1.1318646612469008d9 -8.457695758685169d-11) + -1.3382659929385544d19) + +(my-assert + (/ -7.978772126259147d9 6.210468872769038d-11) + -1.2847294286013678d20) + +(my-assert + (/ -9.057338243339752d9 7.364415429198257d-11) + -1.2298787772658011d20) + +(my-assert + (/ -5.341117220720213d9 4.7359651161519756d-11) + -1.1277779902779204d20) + +(my-assert + (/ 5.838003830912871d9 -5.0625478501901024d-11) + -1.153175042225754d20) + +(my-assert + (/ 6.407156672927742d9 5.006339136594536d19) + 1.279808758079079d-10) + +(my-assert + (/ 4.687485139826675d8 -3.5561755068968083d19) + -1.3181253655045475d-11) + +(my-assert + (/ -5.838044723576891d9 -6.843985743599882d19) + 8.530182473036721d-11) + +(my-assert + (/ 3.9279221543350096d9 -5.882918042982924d19) + -6.67682623765291d-11) + +(my-assert + (/ -9.686323716926361d9 -3.44800215666902d19) + 2.8092568614527606d-10) + +(my-assert + (/ 7.301304808910639d9 1.2845297359643038d19) + 5.684029419085038d-10) + +(my-assert + (/ 4.380345662298534d9 -4.352751895415198d-21) + -1.0063393842668593d30) + +(my-assert + (/ 8.239490918139045d9 3.2397577733346748d-21) + 2.5432428886984834d30) + +(my-assert + (/ 3.8980499504872713d9 8.311650110069505d-21) + 4.689862901910189d29) + +(my-assert + (/ -9.425472285331268d9 -3.294031046828316d-21) + 2.861379310436876d30) + +(my-assert + (/ 2.517833161624173d9 3.6891560299469316d-21) + 6.824957093669991d29) + +(my-assert + (/ -5.463519676339016d9 -7.298583081866205d-22) + 7.485726496576409d30) + +(my-assert + (/ 1.39357009199772d-11 0.417842407627649d0) + 3.335157146709649d-11) + +(my-assert + (/ 8.58494900746665d-11 -0.6481371063028898d0) + -1.3245575548724563d-10) + +(my-assert + (/ -9.310282234439046d-11 0.9146343299129254d0) + -1.0179239866631073d-10) + +(my-assert + (/ -8.800556770159418d-11 -0.9305573406536135d0) + 9.45729659601417d-11) + +(my-assert + (/ -1.3361456473382827d-11 0.06420301636905124d0) + -2.081125970247039d-10) + +(my-assert + (/ 6.1406425153971765d-12 -0.3082496074575478d0) + -1.992100676476244d-11) + +(my-assert + (/ -3.6962256202372035d-11 3.089420488573177d9) + -1.1964139015418631d-20) + +(my-assert + (/ -6.145126590884831d-11 -6.225608984106817d9) + 9.870723661849874d-21) + +(my-assert + (/ 9.052281678541901d-11 -6.9187138778508625d9) + -1.3083763598782874d-20) + +(my-assert + (/ -3.4950245360118636d-11 7.543342567738434d9) + -4.633257080169575d-21) + +(my-assert + (/ -3.482822570743636d-11 -3.87599225187502d9) + 8.985628309909062d-21) + +(my-assert + (/ -9.42226868788213d-11 7.501937454180854d9) + -1.2559780383974101d-20) + +(my-assert + (/ -4.8165035309367155d-11 9.484620130429997d-11) + -0.5078225026096383d0) + +(my-assert + (/ 6.880022773725747d-11 -9.699156104509544d-11) + -0.7093424107822056d0) + +(my-assert + (/ 1.5817962388036865d-11 -7.11651152335492d-11) + -0.22227129593095693d0) + +(my-assert + (/ -7.0140750853949335d-12 -4.4677941652531186d-11) + 0.15699190307254357d0) + +(my-assert + (/ -2.6947489262085355d-11 8.365454450205894d-11) + -0.3221282169723859d0) + +(my-assert + (/ 8.703167674410303d-11 -4.88739813223768d-11) + -1.7807363834354917d0) + +(my-assert + (/ 1.165112061543483d-12 -5.899528740399518d19) + -1.9749239520860124d-32) + +(my-assert + (/ 7.126386981630328d-12 5.091741402945837d19) + 1.3995971942933598d-31) + +(my-assert + (/ -7.132349854872655d-13 7.70347159367981d19) + -9.258617712985763d-33) + +(my-assert + (/ 4.507266517270466d-11 -1.6192737232544485d19) + -2.7835111831566513d-30) + +(my-assert + (/ -3.025128309814261d-11 -5.606736896306867d19) + 5.395523930874836d-31) + +(my-assert + (/ -5.390258677516223d-11 6.628750121976767d18) + -8.131636550373976d-30) + +(my-assert + (/ -8.484515181627938d-11 6.226893371743352d-21) + -1.3625598954575508d10) + +(my-assert + (/ 5.110456708789676d-11 -7.434814854731122d-21) + -6.873683889434922d9) + +(my-assert + (/ -7.784815533665352d-11 -8.942884975553875d-21) + 8.705038200698988d9) + +(my-assert + (/ 6.06871371776654d-11 -8.4720755768444d-21) + -7.163195916657484d9) + +(my-assert + (/ 6.395725883763629d-11 3.2465500186809204d-21) + 1.970006883295217d10) + +(my-assert + (/ 8.23766365482318d-11 3.5665958051648335d-21) + 2.3096712116618633d10) + +(my-assert + (/ -6.882125490660233d19 0.680553203393516d0) + -1.0112545876418106d20) + +(my-assert + (/ -8.955858402134752d19 0.11144092291315044d0) + -8.03641801236189d20) + +(my-assert + (/ 4.517225460957592d19 -0.5804969398143229d0) + -7.781652496570381d19) + +(my-assert + (/ -9.741926397385082d19 -0.9037000739789977d0) + 1.0780043819728059d20) + +(my-assert + (/ 9.654390326446178d19 -0.061963385089831124d0) + -1.558079874501655d21) + +(my-assert + (/ 9.50855454738802d19 0.30375471599023185d0) + 3.130339727036138d20) + +(my-assert + (/ 4.323538184184934d19 -2.6027608151521606d9) + -1.661135421670383d10) + +(my-assert + (/ 4.0554081767557594d17 4.814123702784068d9) + 8.423979995384136d7) + +(my-assert + (/ 5.12727309625028d19 1.761988796449604d9) + 2.9099351293162037d10) + +(my-assert + (/ -7.335661993746345d19 -4.961351435504d9) + 1.4785612527368061d10) + +(my-assert + (/ 3.7135994768593306d18 3.273427798269768d8) + 1.1344681189614824d10) + +(my-assert + (/ 1.3911083524706402d19 8.651242909451927d9) + 1.6079866985942366d9) + +(my-assert + (/ 6.473382688386894d19 -3.700509647679497d-11) + -1.7493219325738552d30) + +(my-assert + (/ 7.25328632809461d19 6.793518758100849d-11) + 1.0676773828651782d30) + +(my-assert + (/ 7.053090091571119d19 8.009021819073383d-11) + 8.806431360661643d29) + +(my-assert + (/ -1.6322872380348074d19 -1.234889420758779d-11) + 1.3218084231637898d30) + +(my-assert + (/ -7.716951191497702d19 -2.473367210466666d-11) + 3.12001839388891d30) + +(my-assert + (/ -2.1174708383466066d19 -9.66632270128099d-11) + 2.1905650202077337d29) + +(my-assert + (/ 4.0902039392392786d18 -5.029423690873208d19) + -0.08132549951322827d0) + +(my-assert + (/ 1.4562115759233494d17 4.2665150414889705d19) + 0.0034131171735308037d0) + +(my-assert + (/ -3.309692589578652d19 1.1329455009949342d19) + -2.9213166799922274d0) + +(my-assert + (/ 3.059130103268258d19 -7.719433592654628d19) + -0.3962894513632647d0) + +(my-assert + (/ 5.622979366632147d19 -8.407251901594788d19) + -0.6688248945610293d0) + +(my-assert + (/ -7.457587910839625d18 1.102755747735572d19) + -0.6762683328700153d0) + +(my-assert + (/ 1.2026615920578564d19 -3.77964792582931d-21) + -3.1819407935832407d39) + +(my-assert + (/ -2.74643694419756d19 2.538907641816601d-22) + -1.0817396028760112d41) + +(my-assert + (/ 8.267361397156658d18 -4.986401395715489d-21) + -1.6579815263689556d39) + +(my-assert + (/ 9.876393891158812d19 -5.792612775193684d-22) + -1.7049981199250076d41) + +(my-assert + (/ 3.927461252713038d17 4.810589424292295d-21) + 8.164199656866003d37) + +(my-assert + (/ 7.29943837795987d19 -4.8820727437034755d-21) + -1.4951514983823475d40) + +(my-assert + (/ -7.837850970911807d-21 0.41514160181315674d0) + -1.8879945870708947d-20) + +(my-assert + (/ 1.1499234744049124d-21 0.4643166529612681d0) + 2.4765932194571437d-21) + +(my-assert + (/ -1.094368243984769d-21 0.9008053219044149d0) + -1.2148776404552516d-21) + +(my-assert + (/ 2.4821206327531197d-21 0.22988631081892086d0) + 1.0797165885654937d-20) + +(my-assert + (/ -4.56226662576732d-22 0.6695285124602162d0) + -6.814148375851899d-22) + +(my-assert + (/ 6.442796853653397d-21 -0.0419134640377401d0) + -1.5371663978553802d-19) + +(my-assert + (/ -5.584403218169678d-21 -8.092869169805251d9) + 6.9003997235062955d-31) + +(my-assert + (/ -9.796722996869492d-21 -3.2988270899833827d9) + 2.9697594719700335d-30) + +(my-assert + (/ 9.441829923771915d-22 5.464575083746736d9) + 1.7278250877830762d-31) + +(my-assert + (/ -6.419360319610147d-21 -7.333962810289677d9) + 8.752921831841952d-31) + +(my-assert + (/ 7.973734412555454d-21 -9.367577614661436d9) + -8.512055880994846d-31) + +(my-assert + (/ 8.105484193881594d-21 -8.664550975192905d9) + -9.354765431108951d-31) + +(my-assert + (/ -5.3151708182942476d-21 -3.406928289732576d-11) + 1.560106455516696d-10) + +(my-assert + (/ -7.026602845639829d-21 -9.92483846943868d-11) + 7.079815824989677d-11) + +(my-assert + (/ -5.901970468193158d-21 2.074489043942647d-11) + -2.8450236868815825d-10) + +(my-assert + (/ -6.40466723844613d-21 -2.551008177490094d-11) + 2.510641594550906d-10) + +(my-assert + (/ 8.056066940872177d-21 4.645883100460603d-11) + 1.7340227394170724d-10) + +(my-assert + (/ 7.453765056481805d-21 6.956136187014756d-11) + 1.0715381148511711d-10) + +(my-assert + (/ 7.357434693258832d-21 -7.093525088486332d19) + -1.0372042956753416d-40) + +(my-assert + (/ -3.3759558579798473d-21 9.991075630444324d19) + -3.3789713769084054d-41) + +(my-assert + (/ 6.908026973557955d-21 -4.20805893397862d19) + -1.6416183998227845d-40) + +(my-assert + (/ 5.181767322756247d-21 7.46986056263721d19) + 6.936899664063931d-41) + +(my-assert + (/ -5.7217313601659264d-21 5.604979023134118d19) + -1.0208301113260054d-40) + +(my-assert + (/ -9.340193892824771d-21 9.147101848766205d19) + -1.021109641857176d-40) + +(my-assert + (/ 8.331002176099931d-21 2.0276444314093977d-21) + 4.108709617449606d0) + +(my-assert + (/ -3.747505523684784d-21 4.394623185543803d-21) + -0.8527478615259381d0) + +(my-assert + (/ -3.310403953328861d-21 2.3420390876737627d-21) + -1.413470838617356d0) + +(my-assert + (/ 6.23845405853013d-21 -8.933620117412232d-21) + -0.6983119918397873d0) + +(my-assert + (/ -4.276770609150315d-21 6.853299965034864d-21) + -0.624045442483205d0) + +(my-assert + (/ -8.847946637724495d-21 6.33827952828724d-21) + -1.3959539963860554d0) + +;; ==== L O N G - F L O A T S ==== + +;; ---- Test von + --- + +(my-assert + (+ 0.31465012912061093874L0 -0.07221963987249409544L0) + 0.2424304892481168433L0) + +(my-assert + (+ 0.7168586654865411176L0 -0.19348808923554474066L0) + 0.52337057625099637695L0) + +(my-assert + (+ -0.64115701400120904706L0 0.70535558267169594756L0) + 0.0641985686704869005L0) + +(my-assert + (+ -0.8607621650923123159L0 0.8368256394262067108L0) + -0.023936525666105605082L0) + +(my-assert + (+ 0.44168990042410450855L0 -0.6041911435521196045L0) + -0.16250124312801509594L0) + +(my-assert + (+ 0.0234267775301613878L0 -0.43594485933986284478L0) + -0.41251808180970145698L0) + +(my-assert + (+ -0.99559578594307881024L0 -9.836107054378142702L9) + -9.836107055373738488L9) + +(my-assert + (+ -0.72423071295455899397L0 9.238843039595790172L9) + 9.238843038871559459L9) + +(my-assert + (+ -0.20719390117857393156L0 -9.029224604657100362L9) + -9.029224604864294263L9) + +(my-assert + (+ 0.20816015380514039224L0 -7.4782571284307568003L9) + -7.4782571282225966468L9) + +(my-assert + (+ -0.16613875159201114463L0 -1.203554507952656804L9) + -1.2035545081187955556L9) + +(my-assert + (+ -0.9837368636729942673L0 7.5892747601936916704L9) + 7.5892747592099548066L9) + +(my-assert + (+ -0.92391870362276300936L0 -5.309205414965326826L-11) + -0.9239187036758550635L0) + +(my-assert + (+ -0.2308075581152660786L0 -2.5400598439608570973L-11) + -0.23080755814066667704L0) + +(my-assert + (+ 0.5668336039528930528L0 1.9300606943253841182L-12) + 0.56683360395482311353L0) + +(my-assert + (+ -0.19685144163870526662L0 -8.548847281762266571L-11) + -0.19685144172419373944L0) + +(my-assert + (+ 0.053837363417219887007L0 -8.4734948552444605444L-11) + 0.053837363332484938454L0) + +(my-assert + (+ 0.24539562474220232599L0 -1.3753029433519360674L-11) + 0.24539562472844929655L0) + +(my-assert + (+ -0.83198492765474177585L0 -1.0728971972413839207L19) + -1.0728971972413839208L19) + +(my-assert + (+ 0.58494670591273850794L0 -2.6078285749436068966L19) + -2.6078285749436068966L19) + +(my-assert + (+ -0.6489422625947265175L0 5.675479528094312524L19) + 5.675479528094312524L19) + +(my-assert + (+ 0.82416783003308421654L0 3.4337105673864461624L19) + 3.4337105673864461624L19) + +(my-assert + (+ 0.5977825969561704576L0 9.447212597358366985L19) + 9.447212597358366985L19) + +(my-assert + (+ 0.81709616259702447027L0 1.8840697606071622024L19) + 1.8840697606071622024L19) + +(my-assert + (+ 0.99140689029640294337L0 -7.9441986163714183364L-21) + 0.99140689029640294337L0) + +(my-assert + (+ 0.49487318874207713882L0 -2.377409962381832069L-21) + 0.49487318874207713882L0) + +(my-assert + (+ 0.050320977002567080524L0 -1.3329877923173878127L-21) + 0.050320977002567080524L0) + +(my-assert + (+ -0.25724170819862546218L0 7.609825486664252559L-22) + -0.25724170819862546218L0) + +(my-assert + (+ 0.3667308347763138993L0 4.077152141636570548L-21) + 0.3667308347763138993L0) + +(my-assert + (+ 0.5130660492586603372L0 -5.091230019243679202L-21) + 0.5130660492586603372L0) + +(my-assert + (+ 8.916053557053472733L8 0.59999700846599703845L0) + 8.916053563053442818L8) + +(my-assert + (+ 1.250980635471676891L9 -0.46325398810664378442L0) + 1.2509806350084229029L9) + +(my-assert + (+ -5.548594356609427516L9 -0.21577258386321002115L0) + -5.5485943568252001L9) + +(my-assert + (+ 1.06508055885340104636L9 0.8422978396429581549L0) + 1.065080559695698886L9) + +(my-assert + (+ 6.225756677310580186L9 0.49531151031004978726L0) + 6.2257566778058916964L9) + +(my-assert + (+ -2.273191688409860673L9 -0.80983784631745405196L0) + -2.2731916892196985192L9) + +(my-assert + (+ 5.688674258485728496L8 8.2409948814224157357L9) + 8.809862307270988585L9) + +(my-assert + (+ -2.7544302700606018156L9 9.230174236450698873L9) + 6.4757439663900970574L9) + +(my-assert + (+ -4.588747139238971857L9 6.342892129519977196L9) + 1.7541449902810053392L9) + +(my-assert + (+ 1.5275587581475159762L9 4.3720035959575018324L9) + 5.8995623541050178087L9) + +(my-assert + (+ 2.8881760807020099163L9 7.5622154923755766074L9) + 1.0450391573077586524L10) + +(my-assert + (+ 6.1044519092512786468L9 1.3858854402983849103L9) + 7.490337349549663557L9) + +(my-assert + (+ 4.8767035174458515886L9 6.3051681974292703475L-11) + 4.8767035174458515886L9) + +(my-assert + (+ -9.4188975960705796466L8 -8.975187577611984141L-12) + -9.4188975960705796466L8) + +(my-assert + (+ -9.689819354179956828L9 -9.7453604450079548966L-11) + -9.689819354179956828L9) + +(my-assert + (+ 4.987209054002559248L9 9.284991248759031191L-11) + 4.987209054002559248L9) + +(my-assert + (+ -3.5572071813296941216L9 -6.261737879308894803L-11) + -3.5572071813296941216L9) + +(my-assert + (+ -7.5872628366112743053L9 2.2152240842834943001L-11) + -7.5872628366112743053L9) + +(my-assert + (+ 7.0206128338340270845L9 5.9246012493594508704L19) + 5.9246012500615121536L19) + +(my-assert + (+ 5.3017367315254228474L9 -1.0933628665004153848L19) + -1.0933628659702417116L19) + +(my-assert + (+ -6.339538144593375358L9 -8.0543624921112893224L19) + -8.054362492745243137L19) + +(my-assert + (+ -1.6010717980362600647L9 9.973849926670833376L19) + 9.973849926510726196L19) + +(my-assert + (+ 3.2030522063397198562L9 -2.4396867565423101768L19) + -2.4396867562220049562L19) + +(my-assert + (+ 8.8622195973163761245L9 -6.4961266512803550736L19) + -6.496126650394133114L19) + +(my-assert + (+ 5.45529926142043848L9 6.939479435912862762L-21) + 5.45529926142043848L9) + +(my-assert + (+ -4.484627189114150671L9 -1.6571134694524616111L-21) + -4.484627189114150671L9) + +(my-assert + (+ 8.813820141949620774L9 -2.8267147580155665537L-21) + 8.813820141949620774L9) + +(my-assert + (+ -9.972890003927356798L9 -3.0273462676816521264L-21) + -9.972890003927356798L9) + +(my-assert + (+ 6.792889851253184185L9 -5.937539083879130763L-21) + 6.792889851253184185L9) + +(my-assert + (+ -3.2663407400779399923L9 -4.0747082067253115984L-21) + -3.2663407400779399923L9) + +(my-assert + (+ -3.4242541190221825202L-11 -0.71988400153646663195L0) + -0.71988400157070917316L0) + +(my-assert + (+ -7.8906347145510431055L-11 -0.22021321631029436988L0) + -0.22021321638920071702L0) + +(my-assert + (+ -7.486719858997914782L-11 0.38102237422222776873L0) + 0.38102237414736057013L0) + +(my-assert + (+ -2.6956794925506179954L-12 -0.49627581161649902356L0) + -0.49627581161919470304L0) + +(my-assert + (+ -8.312064814531952837L-11 0.5797009072836515581L0) + 0.57970090720053090995L0) + +(my-assert + (+ -4.0305959593285763394L-11 0.16233584979062195143L0) + 0.16233584975031599183L0) + +(my-assert + (+ 3.731977491280278192L-11 3.0305998235716452734L9) + 3.0305998235716452734L9) + +(my-assert + (+ 2.7847304030282320388L-11 -6.146190065628934066L9) + -6.146190065628934066L9) + +(my-assert + (+ -1.1797664511795163538L-11 1.4888590774768513251L9) + 1.4888590774768513251L9) + +(my-assert + (+ -3.736849276790130025L-11 1.9988395869145483342L9) + 1.9988395869145483342L9) + +(my-assert + (+ 5.7818526942690563386L-12 3.5155514714363584847L9) + 3.5155514714363584847L9) + +(my-assert + (+ 1.8183862272066184134L-11 -4.635399960322760982L9) + -4.635399960322760982L9) + +(my-assert + (+ 3.5539523819420841283L-11 4.3044646394847154864L-11) + 7.858417021426799615L-11) + +(my-assert + (+ 8.719537619908441472L-11 -8.580989797275158101L-11) + 1.3854782263328337111L-12) + +(my-assert + (+ 2.49701168436805957L-12 -2.6066406246366064513L-11) + -2.3569394561998004944L-11) + +(my-assert + (+ 4.2774640500882048993L-11 3.7620100241760410496L-11) + 8.039474074264245949L-11) + +(my-assert + (+ 3.9907211434460210612L-11 9.72066373418363098L-11) + 1.3711384877629652041L-10) + +(my-assert + (+ -7.851637932849992129L-11 4.9296626910685147652L-11) + -2.9219752417814773637L-11) + +(my-assert + (+ 3.14874349918113769L-11 -1.8148353890339025639L19) + -1.8148353890339025639L19) + +(my-assert + (+ -8.444922682942673745L-11 -5.0034364072191331772L19) + -5.0034364072191331772L19) + +(my-assert + (+ 4.762299619586316462L-12 -1.3412404578328588061L19) + -1.3412404578328588061L19) + +(my-assert + (+ -9.22833351501850052L-12 3.1000370791158631634L19) + 3.1000370791158631634L19) + +(my-assert + (+ 6.1164399913981911425L-11 6.1863455383782109436L19) + 6.1863455383782109436L19) + +(my-assert + (+ -8.413645565754525347L-11 -2.5034082588556447364L19) + -2.5034082588556447364L19) + +(my-assert + (+ 3.4875247204061292656L-11 -7.8682893445087250245L-21) + 3.487524719619300331L-11) + +(my-assert + (+ -2.1647610944488691768L-11 -8.371089558230910183L-21) + -2.1647610952859781326L-11) + +(my-assert + (+ 5.7598234760228848032L-11 2.8011007358408259187L-21) + 5.7598234763029948767L-11) + +(my-assert + (+ -9.268425959344303144L-11 -6.4655012698265179856L-21) + -9.2684259599908532713L-11) + +(my-assert + (+ 7.067467072298381137L-11 -3.8206328350148818058L-21) + 7.0674670719163178536L-11) + +(my-assert + (+ 7.8912028748606542386L-11 8.456364925917236866L-21) + 7.891202875706290731L-11) + +(my-assert + (+ -6.976183652817340798L18 0.08822040416435015717L0) + -6.976183652817340798L18) + +(my-assert + (+ -1.2414457404200743984L19 -0.85791705029429396234L0) + -1.2414457404200743985L19) + +(my-assert + (+ -8.9687515173878579424L19 -0.3328210335620137057L0) + -8.9687515173878579424L19) + +(my-assert + (+ -5.438581645592863998L19 -0.67774278184358142436L0) + -5.438581645592863998L19) + +(my-assert + (+ -5.4350840695201649084L19 -0.72739900682842943577L0) + -5.4350840695201649084L19) + +(my-assert + (+ 7.814697448090367615L19 0.24326892882624165414L0) + 7.814697448090367615L19) + +(my-assert + (+ -2.4356768540932142124L19 6.5169042447583127604L9) + -2.435676853441523788L19) + +(my-assert + (+ -8.7464253032141704904L19 6.8315507162032823036L9) + -8.7464253025310154184L19) + +(my-assert + (+ -2.4810334273518910993L18 -7.638114077520272164L9) + -2.4810334349900051768L18) + +(my-assert + (+ -9.80334620432051716L19 4.474822777555302305L9) + -9.8033462038730348824L19) + +(my-assert + (+ -1.5185085475715921137L19 8.496315073274781452L9) + -1.5185085467219606064L19) + +(my-assert + (+ -9.3842548893937585184L19 -9.948865349103608366L9) + -9.3842548903886450536L19) + +(my-assert + (+ 5.9391253980818643888L19 5.6213951287112563564L-11) + 5.9391253980818643888L19) + +(my-assert + (+ -4.8270749631022207188L19 6.506986668488438766L-11) + -4.8270749631022207188L19) + +(my-assert + (+ 8.953940231252599753L19 -1.7735448342981541823L-11) + 8.953940231252599753L19) + +(my-assert + (+ -6.1065165153181616235L18 -1.8103764902203059955L-11) + -6.1065165153181616235L18) + +(my-assert + (+ -9.6224955477275161216L19 9.4659333494557267205L-11) + -9.6224955477275161216L19) + +(my-assert + (+ -9.2620034246522033504L19 -8.920063409062509698L-11) + -9.2620034246522033504L19) + +(my-assert + (+ 5.9633456897700879935L18 4.0390945943970882336L19) + 4.6354291633740970328L19) + +(my-assert + (+ -6.1420542659063065884L19 -3.9869088703267959336L19) + -1.01289631362331025216L20) + +(my-assert + (+ 7.804124970286546613L19 8.061318173712112305L19) + 1.5865443143998658918L20) + +(my-assert + (+ -7.763817772329800516L19 -4.9349702057713961232L19) + -1.2698787978101196639L20) + +(my-assert + (+ -3.1480955091040648274L19 -4.706529024129812914L19) + -7.8546245332338777416L19) + +(my-assert + (+ -4.7131343507844737428L19 5.4602299451983202032L19) + 7.470955944138464604L18) + +(my-assert + (+ 5.9403761194093478956L19 -6.280541343011718101L-21) + 5.9403761194093478956L19) + +(my-assert + (+ -3.763295388652278206L19 -9.963494853851408371L-21) + -3.763295388652278206L19) + +(my-assert + (+ 2.5136958358030666948L19 5.335607709622335287L-21) + 2.5136958358030666948L19) + +(my-assert + (+ 6.2273952762016960176L19 -5.6012630121574213906L-21) + 6.2273952762016960176L19) + +(my-assert + (+ -9.3934610912833028936L19 -2.59552531586503232L-21) + -9.3934610912833028936L19) + +(my-assert + (+ 2.9584554660239488776L19 6.875837450751388893L-21) + 2.9584554660239488776L19) + +(my-assert + (+ -8.4905558825256936576L-21 0.112912972443893420624L0) + 0.11291297244389342062L0) + +(my-assert + (+ -5.3259362300699140443L-21 0.44064771529278198132L0) + 0.44064771529278198132L0) + +(my-assert + (+ -9.245572241572266517L-21 0.043497459079983070442L0) + 0.043497459079983070432L0) + +(my-assert + (+ 7.6311333407948593004L-22 0.74437178299084331024L0) + 0.74437178299084331024L0) + +(my-assert + (+ -7.71114100404407176L-21 -0.30667849853816871164L0) + -0.30667849853816871164L0) + +(my-assert + (+ 3.544120177696956032L-21 0.79322122717232419205L0) + 0.79322122717232419205L0) + +(my-assert + (+ 7.7913861181291523115L-21 8.526554352243632931L9) + 8.526554352243632931L9) + +(my-assert + (+ -3.9196632415032070805L-21 -2.5228304289307799614L9) + -2.5228304289307799614L9) + +(my-assert + (+ 7.643174046933518012L-22 2.9248526891356128762L9) + 2.9248526891356128762L9) + +(my-assert + (+ 1.8801815336593227227L-21 6.8178694125314363L9) + 6.8178694125314363L9) + +(my-assert + (+ -2.6985037225367287349L-21 -4.5571976978858014136L9) + -4.5571976978858014136L9) + +(my-assert + (+ 6.0444611510506986126L-21 -8.64585025875790907L9) + -8.64585025875790907L9) + +(my-assert + (+ -1.250177749198396931L-21 6.428634063301101147L-11) + 6.428634063176083372L-11) + +(my-assert + (+ -1.5666058964343815161L-21 3.552568414787808555L-11) + 3.5525684146311479653L-11) + +(my-assert + (+ -5.8078119773790503857L-21 8.896395897015492877L-12) + 8.8963958912076809L-12) + +(my-assert + (+ 6.7472260162031965506L-21 -6.617115409846031908L-11) + -6.617115409171309306L-11) + +(my-assert + (+ -4.16121984125470857L-21 -3.095053467302410671L-11) + -3.095053467718532655L-11) + +(my-assert + (+ -2.114411383443366621L-21 9.716046816037651671L-11) + 9.716046815826210533L-11) + +(my-assert + (+ -2.3406730990296292957L-21 7.900725768498098123L18) + 7.900725768498098123L18) + +(my-assert + (+ -4.1514248667302411754L-21 -8.4325334951006246184L19) + -8.4325334951006246184L19) + +(my-assert + (+ 8.433933541545648577L-21 -4.9459088765496691632L19) + -4.9459088765496691632L19) + +(my-assert + (+ 2.2922577085250648752L-21 7.813245819908182463L19) + 7.813245819908182463L19) + +(my-assert + (+ 8.887270525300553388L-21 8.651116139112459977L19) + 8.651116139112459977L19) + +(my-assert + (+ 1.1406539199130032192L-21 2.3931812472136783544L19) + 2.3931812472136783544L19) + +(my-assert + (+ -3.778523001798117503L-21 2.0779948578933832532L-22) + -3.5707235160087791776L-21) + +(my-assert + (+ -1.6066062689688361383L-21 -3.5232009896946632975L-21) + -5.1298072586634994358L-21) + +(my-assert + (+ 3.9703618511174300454L-21 -8.036088455194107478L-21) + -4.0657266040766774324L-21) + +(my-assert + (+ 6.46657477279861825L-21 2.6384883907642781157L-21) + 9.105063163562896366L-21) + +(my-assert + (+ 4.9706631077050274314L-21 2.3628052244020145395L-21) + 7.333468332107041971L-21) + +(my-assert + (+ 7.065951142271372955L-21 3.1965272324939519L-21) + 1.02624783747653248544L-20) + +;; ---- Test von - --- + +(my-assert + (- 0.3211111183819802968L0 -0.7024866236309383056L0) + 1.0235977420129186024L0) + +(my-assert + (- -0.29770116676264721836L0 0.8494818768850108081L0) + -1.1471830436476580264L0) + +(my-assert + (- -0.7677860965279355367L0 0.9474539728585997539L0) + -1.7152400693865352905L0) + +(my-assert + (- -0.25414380069764370257L0 0.82619594943351718565L0) + -1.0803397501311608883L0) + +(my-assert + (- 0.21685951051311267031L0 0.13084151170902027524L0) + 0.08601799880409239507L0) + +(my-assert + (- -0.6658362643286463323L0 -0.101768362258000388376L0) + -0.56406790207064594393L0) + +(my-assert + (- -0.8594165074009265017L0 3.58724520062188585L9) + -3.5872452014813023575L9) + +(my-assert + (- -0.58779846333918551446L0 -2.8410824560251060135L9) + 2.84108245543730755L9) + +(my-assert + (- 0.37819983918255152712L0 1.75837003745458279L9) + -1.7583700370763829509L9) + +(my-assert + (- -0.19345242719447268632L0 -8.900743696911070234L9) + 8.900743696717617807L9) + +(my-assert + (- 0.9170636757513836193L0 -5.181144559509726756L9) + 5.1811445604267904316L9) + +(my-assert + (- 0.20643137049004858552L0 3.3215544303850617772L9) + -3.3215544301786304067L9) + +(my-assert + (- -0.4014437452394343757L0 4.7898418688154180505L-11) + -0.40144374528733279438L0) + +(my-assert + (- 0.0725076594551243524L0 -3.5321788599004111594L-11) + 0.072507659490446140996L0) + +(my-assert + (- -0.65551702819898271043L0 3.1653130032883009534L-11) + -0.6555170282306358405L0) + +(my-assert + (- 0.9237105409310637695L0 -8.9028024814928743296L-11) + 0.9237105410200917943L0) + +(my-assert + (- 0.8779771368966066218L0 7.399233988536237696L-12) + 0.8779771368892073878L0) + +(my-assert + (- 0.51385216558296334914L0 -3.3989256599054576304L-11) + 0.51385216561695260575L0) + +(my-assert + (- 0.74939199427992763254L0 -6.6998781480191798724L19) + 6.6998781480191798724L19) + +(my-assert + (- 0.8073774220299670944L0 2.0433771569275457978L18) + -2.043377156927545797L18) + +(my-assert + (- -0.75286822781531276375L0 -7.7011647701976081504L19) + 7.7011647701976081504L19) + +(my-assert + (- -0.6361916050116532222L0 1.2717052281488651182L19) + -1.2717052281488651183L19) + +(my-assert + (- 0.08977643006115956575L0 1.2624046205072289204L19) + -1.2624046205072289204L19) + +(my-assert + (- -0.4220171145412169327L0 8.9155115345908061576L19) + -8.9155115345908061576L19) + +(my-assert + (- 0.397772867452284942L0 5.7785851646148710778L-21) + 0.397772867452284942L0) + +(my-assert + (- -0.53062845978690011166L0 -3.648685738612220277L-21) + -0.53062845978690011166L0) + +(my-assert + (- 0.25409096540159836552L0 -7.8088660109317384514L-21) + 0.25409096540159836552L0) + +(my-assert + (- 0.78038095936361252965L0 5.166705522400390383L-21) + 0.78038095936361252965L0) + +(my-assert + (- 0.2384997171475220939L0 9.580584601627251829L-21) + 0.23849971714752209389L0) + +(my-assert + (- 0.38777493167494073L0 -7.930455614605653916L-22) + 0.38777493167494073L0) + +(my-assert + (- 9.34906594120583919L8 -0.06276538462885111519L0) + 9.349065941833493036L8) + +(my-assert + (- 3.8000098261497040978L9 0.08156195452126583918L0) + 3.8000098260681421433L9) + +(my-assert + (- -8.5084000619874580647L9 -0.49084164337509169664L0) + -8.5084000614966164213L9) + +(my-assert + (- -9.367354572017391158L9 0.7369625068937909906L0) + -9.367354572754353665L9) + +(my-assert + (- 6.810025547716964613L9 -0.65456201729278556224L0) + 6.8100255483715266306L9) + +(my-assert + (- -2.0476539871173359762L9 -0.61684944260168028793L0) + -2.0476539865004865336L9) + +(my-assert + (- 7.927587886187347037L9 -9.075678068210342653L9) + 1.700326595439768969L10) + +(my-assert + (- 8.3881162961959078424L9 -8.168276983460029623L9) + 1.6556393279655937465L10) + +(my-assert + (- -9.837108887605194379L9 -5.518197215327419734L9) + -4.3189116722777746445L9) + +(my-assert + (- 6.0530403690423784372L9 -4.794777582812792957L9) + 1.0847817951855171394L10) + +(my-assert + (- -7.6786817362598780694L8 3.0685743382723052597L9) + -3.8364425118982930668L9) + +(my-assert + (- -1.035869943077157163L9 6.964469962306024778L8) + -1.7323169393077596407L9) + +(my-assert + (- -5.236689202734255992L9 -3.2118444581504684365L-12) + -5.236689202734255992L9) + +(my-assert + (- -5.374622629137047618L9 6.0449117144963868685L-11) + -5.374622629137047618L9) + +(my-assert + (- -1.03444332932187716727L9 -7.849504746710041045L-11) + -1.0344433293218771672L9) + +(my-assert + (- 5.1103879354813158946L8 6.53093826849017485L-11) + 5.110387935481315894L8) + +(my-assert + (- -9.748335199611953219L9 -1.0598402609119659922L-11) + -9.748335199611953219L9) + +(my-assert + (- -7.3482164921795502603L9 7.644598674874161005L-11) + -7.3482164921795502603L9) + +(my-assert + (- -7.4770248834652064083L8 -6.510822784079429222L19) + 6.5108227840046589732L19) + +(my-assert + (- 8.3114910321533068423L9 -6.2387352982669333472L19) + 6.2387352990980824504L19) + +(my-assert + (- -1.0718584220381511548L9 8.521462332927085385L19) + -8.521462333034271227L19) + +(my-assert + (- -1.9155322368803175137L8 1.3150623743950738752L19) + -1.3150623744142291976L19) + +(my-assert + (- 3.8652241507510457716L9 8.702412273358053775L19) + -8.70241227297153136L19) + +(my-assert + (- 2.922009617968977308L8 -8.409184530486676791L19) + 8.409184530515896887L19) + +(my-assert + (- -7.3431860804237713437L9 9.020687655591526829L-21) + -7.3431860804237713437L9) + +(my-assert + (- -1.1188563145822172016L9 -2.7575065881283248758L-21) + -1.1188563145822172016L9) + +(my-assert + (- 2.5835681218682880315L9 -3.786022710650191692L-21) + 2.5835681218682880315L9) + +(my-assert + (- 4.3854765424506375063L9 1.8847509423241615905L-21) + 4.3854765424506375063L9) + +(my-assert + (- -3.4713769831512517224L9 -2.322290027198980782L-21) + -3.4713769831512517224L9) + +(my-assert + (- 414355.71501652302632L0 3.5411352752491676944L-21) + 414355.71501652302632L0) + +(my-assert + (- 9.032857346451659148L-11 0.45111022909893884074L0) + -0.45111022900861026729L0) + +(my-assert + (- -6.5860623447077106086L-11 -0.16349916999618723413L0) + 0.16349916993032661068L0) + +(my-assert + (- -9.239429491581222244L-11 0.34742997377809253703L0) + -0.34742997387048683193L0) + +(my-assert + (- -1.3189202177704638207L-11 0.6447775025861344695L0) + -0.64477750259932367166L0) + +(my-assert + (- -8.6095719029859522596L-11 0.36611643318066821885L0) + -0.3661164332667639379L0) + +(my-assert + (- -7.9284738631391966236L-11 -0.28883099180012157807L0) + 0.28883099172083683944L0) + +(my-assert + (- -9.9602023259578447484L-11 8.944817052366967221L9) + -8.944817052366967221L9) + +(my-assert + (- -4.7036434158090755064L-11 -7.652311009876441256L9) + 7.652311009876441256L9) + +(my-assert + (- -7.237899450242616437L-11 -2.0865196011945540415L9) + 2.0865196011945540414L9) + +(my-assert + (- 1.619466049424876382L-11 5.1184733211578935236L9) + -5.1184733211578935236L9) + +(my-assert + (- 4.1799408897021043963L-11 7.3289378733409777703L9) + -7.3289378733409777703L9) + +(my-assert + (- -7.1652994078281664426L-11 -8.756819754593247181L9) + 8.756819754593247181L9) + +(my-assert + (- -3.7074082585707708083L-11 7.8185038704847907146L-11) + -1.1525912129055561523L-10) + +(my-assert + (- -6.236585731179139659L-11 7.2778046100364844843L-11) + -1.3514390341215624144L-10) + +(my-assert + (- 4.435573645212270856L-11 -5.0777570123416204425L-11) + 9.5133306575538912986L-11) + +(my-assert + (- -8.308776483243665939L-11 9.147453931535851365L-11) + -1.7456230414779517304L-10) + +(my-assert + (- 9.9047307392438733836L-11 -2.5521271062995892868L-11) + 1.245685784554346267L-10) + +(my-assert + (- 7.964304540045338675L-11 -8.2763721216842256806L-11) + 1.6240676661729564355L-10) + +(my-assert + (- 6.3981149909251410836L-11 -8.199461198383311753L19) + 8.199461198383311753L19) + +(my-assert + (- 3.2676777703423324814L-11 4.4068061681801047868L19) + -4.4068061681801047868L19) + +(my-assert + (- -6.239367423070186989L-11 3.6883672788938434168L19) + -3.6883672788938434168L19) + +(my-assert + (- -2.2122757699951901351L-11 2.1264312306673926188L19) + -2.1264312306673926188L19) + +(my-assert + (- 8.873182931301984606L-11 1.6930709481447417272L19) + -1.6930709481447417272L19) + +(my-assert + (- -6.88393272917067128L-11 9.590650870092490293L19) + -9.590650870092490293L19) + +(my-assert + (- 6.858643038376546876L-11 7.344128953107545512L-21) + 6.858643037642133981L-11) + +(my-assert + (- 2.6458055358368033053L-11 5.403788941414579396L-21) + 2.6458055352964244111L-11) + +(my-assert + (- -2.0808117056914325832L-11 -9.598437242399057154L-21) + -2.080811704731588859L-11) + +(my-assert + (- -6.7475294377176982065L-11 7.066634775850918749L-21) + -6.747529438424361684L-11) + +(my-assert + (- -9.3542684131795074026L-11 -2.671834604826394793L-22) + -9.354268413152789057L-11) + +(my-assert + (- -3.656675383727620855L-11 -5.7226858095399702763L-21) + -3.656675383155352274L-11) + +(my-assert + (- 4.4004114393746579576L19 0.9981645829158248139L0) + 4.4004114393746579576L19) + +(my-assert + (- -2.1157157847974045162L19 -0.73136590134089295135L0) + -2.1157157847974045162L19) + +(my-assert + (- -6.58288354566033103L19 0.6435204448077814454L0) + -6.58288354566033103L19) + +(my-assert + (- -6.1300052513232283715L18 0.37782114066015354996L0) + -6.130005251323228372L18) + +(my-assert + (- -8.3428987469650376416L19 0.092302889297602909923L0) + -8.3428987469650376416L19) + +(my-assert + (- 4.478146018721476673L18 -0.7594367116407568048L0) + 4.4781460187214766738L18) + +(my-assert + (- 3.9553793567888621644L19 7.272309486263127643L9) + 3.9553793560616312156L19) + +(my-assert + (- 8.4985452245750157485L18 -8.180191224624705388L9) + 8.498545232755206973L18) + +(my-assert + (- -4.9006940756698268444L19 5.635530637330344937L9) + -4.900694076233379908L19) + +(my-assert + (- 3.321094625885548145L19 7.739325488496469393L9) + 3.3210946251116155962L19) + +(my-assert + (- -4.094717236852398814L19 2.8833151826524522544L9) + -4.0947172371407303324L19) + +(my-assert + (- -7.297938416992967256L19 1.7849049534461509205L9) + -7.2979384171714577512L19) + +(my-assert + (- -1.6274534493365811085L19 -7.214220253590898893L-11) + -1.6274534493365811085L19) + +(my-assert + (- -8.8349360721401487896L19 4.4201546048906225832L-11) + -8.8349360721401487896L19) + +(my-assert + (- 2.1193875854469716176L19 5.4852102858193519493L-11) + 2.1193875854469716176L19) + +(my-assert + (- 5.8956188285652689564L19 5.2591781987716878005L-12) + 5.8956188285652689564L19) + +(my-assert + (- 3.8130742288947136824L19 -6.2032926048476626596L-11) + 3.8130742288947136824L19) + +(my-assert + (- -8.2648264381835919784L19 5.240041099543619651L-11) + -8.2648264381835919784L19) + +(my-assert + (- -8.9795702979594840016L19 5.3071479395700422216L19) + -1.4286718237529526223L20) + +(my-assert + (- 7.4902067869555502376L19 8.527286348112666809L18) + 6.6374781521442835568L19) + +(my-assert + (- -9.945686226441305483L19 -7.164943842935287866L19) + -2.7807423835060176172L19) + +(my-assert + (- -6.9451908461424534725L18 1.7337328244166615333L19) + -2.4282519090309068806L19) + +(my-assert + (- -7.2554820480127785552L19 -3.6345553532831870424L19) + -3.6209266947295915128L19) + +(my-assert + (- 4.80739562024854996L19 -9.8058600290712759904L19) + 1.46132556493198259504L20) + +(my-assert + (- -2.2910115296639597206L19 3.7450560231732721633L-21) + -2.2910115296639597206L19) + +(my-assert + (- 6.3398397438838205245L18 5.9452907771459291318L-21) + 6.3398397438838205245L18) + +(my-assert + (- -3.6223171453314706578L19 -7.3897558037422565484L-21) + -3.6223171453314706578L19) + +(my-assert + (- -5.253323265732561348L19 -2.4894382246759080012L-21) + -5.253323265732561348L19) + +(my-assert + (- 8.706482285826808214L18 -5.353671688426432468L-21) + 8.706482285826808214L18) + +(my-assert + (- 2.2257683364797036278L18 -8.640543721759613242L-21) + 2.2257683364797036278L18) + +(my-assert + (- 4.793610535063041737L-21 -0.46707949288138879385L0) + 0.46707949288138879385L0) + +(my-assert + (- -8.1177127707349576126L-22 -0.524723160625887566L0) + 0.524723160625887566L0) + +(my-assert + (- 4.3845050204409245572L-21 0.25137862247046227512L0) + -0.25137862247046227512L0) + +(my-assert + (- 9.521149905664397992L-21 -0.8412363166750659234L0) + 0.8412363166750659234L0) + +(my-assert + (- 9.174773471390805996L-21 -0.101196005202611894716L0) + 0.10119600520261189472L0) + +(my-assert + (- 7.109559498077443181L-21 0.9205539164614073537L0) + -0.9205539164614073537L0) + +(my-assert + (- 4.698785699006337068L-21 -2.1800327611972026394L9) + 2.1800327611972026394L9) + +(my-assert + (- 5.613624265510662971L-21 -9.950548243828975189L9) + 9.950548243828975189L9) + +(my-assert + (- 4.6909741937286841078L-21 -1.7837781830572891826L9) + 1.7837781830572891826L9) + +(my-assert + (- -4.846242463794952647L-21 -8.0162418694778434667L9) + 8.0162418694778434667L9) + +(my-assert + (- 2.40959428070040729L-21 -8.889381116534260471L9) + 8.889381116534260471L9) + +(my-assert + (- 3.767840665510686708L-21 -6.5742819327593306936L9) + 6.5742819327593306936L9) + +(my-assert + (- -4.2984578582437655097L-21 -7.11707524430297521L-11) + 7.117075243873129424L-11) + +(my-assert + (- -8.2197602823824843314L-21 5.6157517586290544195L-11) + -5.6157517594510304478L-11) + +(my-assert + (- 9.693403466151038911L-21 -2.4790192993953556532L-11) + 2.4790193003646959998L-11) + +(my-assert + (- -1.7473025967684817638L-21 -6.763791909706180161L-11) + 6.763791909531449901L-11) + +(my-assert + (- -4.545821853960128388L-21 -2.0149758755990572603L-11) + 2.0149758751444750749L-11) + +(my-assert + (- -6.727743751498960878L-21 4.6105155267302345166L-11) + -4.6105155274030088917L-11) + +(my-assert + (- 3.1693009676315354841L-21 -8.292132887357976433L19) + 8.292132887357976433L19) + +(my-assert + (- -1.5197222855116101305L-21 -6.8790212191073234628L19) + 6.8790212191073234628L19) + +(my-assert + (- 9.221684449614781083L-21 -5.9085200983462461748L19) + 5.9085200983462461748L19) + +(my-assert + (- 8.784720275148798145L-21 -3.507151222326700691L19) + 3.507151222326700691L19) + +(my-assert + (- 3.824100155304652155L-21 1.2903444775641864255L19) + -1.2903444775641864255L19) + +(my-assert + (- -1.0750770892330241413L-21 2.516785805333378789L19) + -2.516785805333378789L19) + +(my-assert + (- -9.607606672669937465L-21 2.8158700323501294737L-21) + -1.2423476705020066939L-20) + +(my-assert + (- 7.9685140548406097L-21 -1.4252185339263422407L-21) + 9.393732588766951941L-21) + +(my-assert + (- -3.1900732903251523987L-21 1.30212230775860485605L-21) + -4.4921955980837572548L-21) + +(my-assert + (- 2.845180721925488069L-21 9.0340678136597289194L-21) + -6.1888870917342408505L-21) + +(my-assert + (- -5.1500491616497403683L-21 -5.4818765813663490764L-21) + 3.3182741971660870814L-22) + +(my-assert + (- 5.3946808417918276896L-21 2.1630450195342998269L-21) + 3.2316358222575278627L-21) + +;; ---- Test von * --- + +(my-assert + (* 0.49162375558276684976L0 -0.27595139770835290185L0) + -0.13566426249969417521L0) + +(my-assert + (* -0.43085705615141429406L0 0.76537655129782028376L0) + -0.32976788773950077688L0) + +(my-assert + (* -0.34725675573811781168L0 -0.44040731024013641718L0) + 0.15293441375734052306L0) + +(my-assert + (* -0.47158645084591665022L0 -0.5531952534025612003L0) + 0.26087938617692133303L0) + +(my-assert + (* -0.86377959068682791106L0 -0.8711108145957097161L0) + 0.7524477428743513754L0) + +(my-assert + (* 0.07688091831246728666L0 -0.727039245375017451L0) + -0.055895444833634576195L0) + +(my-assert + (* -0.65693719777446694155L0 -5.4929597366864347663L9) + 3.6085295769067602507L9) + +(my-assert + (* 0.9553509506606886749L0 2.7316499794256227606L9) + 2.609684404716519364L9) + +(my-assert + (* 0.86245066819702621825L0 -5.6471738746979076876L9) + -4.8704088816580000957L9) + +(my-assert + (* -0.0011095142242845852372L0 3.5868904614046262004L9) + -3979705.9878791318615L0) + +(my-assert + (* -0.07537979049336559763L0 8.268739091555253606L9) + -6.2329582036573719373L8) + +(my-assert + (* -0.67924101443000006024L0 -4.2094803212494913754L9) + 2.8592516836286270604L9) + +(my-assert + (* 0.30774277681107480866L0 -2.7334742019139702906L-11) + -8.412069412384417957L-12) + +(my-assert + (* -0.35713749207523871768L0 -6.5398928539622633783L-11) + 2.3356409323048581577L-11) + +(my-assert + (* -0.14801577485738927266L0 -9.963460779718656755L-11) + 1.474749367571264873L-11) + +(my-assert + (* 0.3104124542612814659L0 -2.9286317751062608258L-11) + -9.09083776938307737L-12) + +(my-assert + (* -0.11446530018625016218L0 6.4232974401995419684L-11) + -7.352446696780128213L-12) + +(my-assert + (* -0.96939447601348607505L0 4.1094462170225605183L-11) + -3.9836744622561876338L-11) + +(my-assert + (* 0.051486415762180288123L0 9.676829213398296352L19) + 4.9822525214063672425L18) + +(my-assert + (* 0.6313327973134614946L0 3.2653448877462378072L19) + 2.06151932217404323L19) + +(my-assert + (* -0.37403303660944479204L0 9.102796469067070187L19) + -3.4047466049628882508L19) + +(my-assert + (* 0.8707828063294901403L0 -5.5603708853312765524L19) + -4.8418753637615606188L19) + +(my-assert + (* -0.21026381134874289964L0 -8.2572592232280544185L18) + 1.7362027955704909688L18) + +(my-assert + (* -0.77817271482774886984L0 -5.862569134483721118L19) + 4.5620913392465632268L19) + +(my-assert + (* 0.10774233598980040668L0 8.42277329172514105L-21) + 9.074892699629673044L-22) + +(my-assert + (* 0.25190108887664378198L0 9.9261121984538427104L-21) + 2.5003984711022594346L-21) + +(my-assert + (* -0.6756036645959631085L0 9.531794528346356556L-21) + -6.4397153135265482465L-21) + +(my-assert + (* -0.6857203923976410447L0 -1.6874445000752253093L-21) + 1.1571151047408247225L-21) + +(my-assert + (* -0.44633489376857998266L0 2.2805928928283052886L-21) + -1.0179081865499001544L-21) + +(my-assert + (* 0.6194914893234261562L0 6.122106446320417613L-21) + 3.7925928402275834338L-21) + +(my-assert + (* 6.0914569120648219218L9 -0.13082334282848865785L0) + -7.969047559320230858L8) + +(my-assert + (* 3.6214037646489572409L9 -0.42724054260765242458L0) + -1.5472105094100157093L9) + +(my-assert + (* -2.3587970682548096273L9 0.30389573937962490564L0) + -7.168283791037869264L8) + +(my-assert + (* -1.2092840284272862272L9 -0.9464357317324953064L0) + 1.1445096143169982957L9) + +(my-assert + (* 9.742195251878672378L9 -0.8436238049826486367L0) + -8.2187478272737786206L9) + +(my-assert + (* -1.6670311480587791415L9 -0.7664626357070004785L0) + 1.277717087546798815L9) + +(my-assert + (* -9.63709082566058824L8 3.5038182805272664595L9) + -3.376661500605117691L18) + +(my-assert + (* -6.819958133674458717L9 5.570090504807835795L9) + -3.7987784043567071428L19) + +(my-assert + (* 5.7990616985027046753L9 5.7633314369957429715L9) + 3.3421914592058566914L19) + +(my-assert + (* -8.4466610113280742876L9 -8.965949996407538079L9) + 7.5732340264172639616L19) + +(my-assert + (* -7.670563670654851578L9 -6.431751468798164421L9) + 4.9335159155244181172L19) + +(my-assert + (* 8.268803418474998627L9 -6.6310260568279516366L9) + -5.4830650926695757004L19) + +(my-assert + (* -9.461472353405244053L9 -3.3101188730107237675L-11) + 0.31318598203475886787L0) + +(my-assert + (* 6.8579221981166585744L9 -8.515361268298587097L-11) + -0.5839768506684770405L0) + +(my-assert + (* 1.6137913170162297342L9 -8.897666779537493419L-11) + -0.14358977390521366923L0) + +(my-assert + (* 8.022366744559274285L9 6.8759798363047156095L-11) + 0.5516163197503107306L0) + +(my-assert + (* 6.268637730252729325L8 3.8798987053952144677L-13) + 2.4321679414199160154L-4) + +(my-assert + (* 8.165455714479826517L9 -7.748491839935670887L-11) + -0.6326996697300302909L0) + +(my-assert + (* -9.245309913477613381L9 -2.7267702243723164598L19) + 2.5209835787164953515L29) + +(my-assert + (* 9.113617507957836761L9 -3.6781774780542862056L19) + -3.3521502661371744663L29) + +(my-assert + (* 3695599.756951605604L0 -4.4160607831464309996L19) + -1.6319993156879467502L26) + +(my-assert + (* -3.1080975558777002585L9 4.5635619314557275256L19) + -1.41839956852540638L29) + +(my-assert + (* 4.379846040113489209L9 -2.380244519018666713L19) + -1.0425104531125744157L29) + +(my-assert + (* 7.799437686108443071L9 -8.213835920178370665L19) + -6.40633014233504056L29) + +(my-assert + (* -5.0032293022496024175L9 3.9947928432298324106L-21) + -1.9986864609664499789L-11) + +(my-assert + (* 5.1002825856458055377L9 -8.630588067810955288L-21) + -4.4018438026138695895L-11) + +(my-assert + (* -1.4798783656292287931L9 -2.1821599778945012917L-21) + 3.2293313416280286032L-12) + +(my-assert + (* 6.2153176651245460436L9 -4.842239650508967686L-21) + -3.009605763857489489L-11) + +(my-assert + (* 1.1476929860538426329L9 8.143327858153323155L-21) + 9.34604026593943011L-12) + +(my-assert + (* -6.8097130569212408313L9 -4.5006072118169309446L-21) + 3.0647843694383655263L-11) + +(my-assert + (* -8.088711469864653681L-11 0.55856748494727835656L0) + -4.518091222186502735L-11) + +(my-assert + (* 4.4880121763658923538L-11 0.14537105272497022953L0) + 6.52427054720794526L-12) + +(my-assert + (* 2.0273639671422034382L-11 0.5267742506127895251L0) + 1.0679631345107062621L-11) + +(my-assert + (* -9.078881981481347403L-11 0.86040896737522678964L0) + -7.811551470607918988L-11) + +(my-assert + (* -7.2713602444015266416L-11 0.029963115152720655096L0) + -2.1787260431991794891L-12) + +(my-assert + (* 5.8587076221559354985L-11 0.39205420166003709617L0) + 2.2969309395639195554L-11) + +(my-assert + (* 9.465227148840012531L-12 -8.4020295562921954743L9) + -0.07952711826157309293L0) + +(my-assert + (* -9.156088652050785426L-11 -7.272635024207867507L9) + 0.66588891015656744834L0) + +(my-assert + (* 3.6865969618651574387L-11 4.532198690564411727L9) + 0.16708389923204005057L0) + +(my-assert + (* -7.773548969171738747L-11 6.487140494299404015L9) + -0.5042810430233337584L0) + +(my-assert + (* 3.181536837232243521L-12 -8.8275599983550392825L8) + -0.0028085207317644360498L0) + +(my-assert + (* 3.512130320642090343L-11 -6.775467122704530228L9) + -0.23796323518164203024L0) + +(my-assert + (* -7.489684894543042722L-11 1.3562671200654034619L-11) + -1.015801336211924759L-21) + +(my-assert + (* -6.615171167169027831L-11 6.4492881876773102747L-11) + -4.2663145267886736825L-21) + +(my-assert + (* 5.9969037329081164062L-12 6.979117807067958578L-11) + 4.1853097629611348155L-22) + +(my-assert + (* -9.1419010578306515213L-11 -3.0321662473944421986L-11) + 2.7719763824573648138L-21) + +(my-assert + (* 8.653994294784604749L-11 -2.618325063862645785L-12) + -2.2658970164558872502L-22) + +(my-assert + (* 3.778177082827084054L-11 5.7986141594804582746L-11) + 2.1908191129505701787L-21) + +(my-assert + (* 9.107023861930220456L-11 -8.1609888558011610015L18) + -7.432232024672778029L8) + +(my-assert + (* -6.185675579794400257L-11 8.145498215172660237L19) + -5.0385409394852397568L9) + +(my-assert + (* -5.0086846264250856304L-12 7.333671928137704804L19) + -3.6732049841708537418L8) + +(my-assert + (* -6.133300578664362783L-11 -4.647031661618042392L19) + 2.8501641979273554706L9) + +(my-assert + (* 4.014159298839782726L-12 7.077385833663047478L18) + 2.8409754155675469803L7) + +(my-assert + (* 3.9529027598797003857L-11 3.1931221840357166776L19) + 1.2622101493907881026L9) + +(my-assert + (* 5.2407793550579649295L-11 8.178146405814506225L-21) + 4.2859860846234161862L-31) + +(my-assert + (* -4.5792905534935737864L-11 -1.1970719995732820388L-21) + 5.481740499497593831L-32) + +(my-assert + (* 4.113879746633747024L-11 5.1093090279978304893L-21) + 2.1019082929573231173L-31) + +(my-assert + (* 1.9918804321687295055L-11 1.8243807936344826748L-21) + 3.6339484036649830696L-32) + +(my-assert + (* -6.1549842617771214656L-11 7.210193834294849238L-22) + -4.4378629574447235495L-32) + +(my-assert + (* -3.483482946766538465L-12 7.8771698631837073084L-22) + -2.743998688718375137L-33) + +(my-assert + (* -3.0540130142847980374L19 -0.08015004741507677209L0) + 2.4477928790118809798L18) + +(my-assert + (* -7.721729897125586787L19 -0.71282981020428696123L0) + 5.5042792570168003116L19) + +(my-assert + (* 6.855667806362567159L18 0.83087248440613607433L0) + 5.69618574253563119L18) + +(my-assert + (* -1.0247670372283575993L17 -0.21215039186338500874L0) + 2.1740472851667611836L16) + +(my-assert + (* -4.2451902701279432204L19 0.363650960045267158L0) + -1.5437675173068535736L19) + +(my-assert + (* -2.3286355030172533736L19 0.49713327148260372132L0) + -1.1576421857055056984L19) + +(my-assert + (* -6.1529172975127592432L19 -7.1685660040728041152L9) + 4.4107593764821477366L29) + +(my-assert + (* 6.7120643409032119372L19 -2.1673488299796731996L9) + -1.45473847960048627434L29) + +(my-assert + (* 8.1354429987417636456L19 -7.205222753181797397L9) + -5.861767900174770815L29) + +(my-assert + (* 7.1263614941049137416L19 5.4835530180135407083L8) + 3.907778107845448494L28) + +(my-assert + (* 5.0833800113097826724L19 -6.2188724451883454807L9) + -3.1612891880755627472L29) + +(my-assert + (* -7.0947371956905508468L19 -2.434705753418370145L9) + 1.7273597469339097183L29) + +(my-assert + (* 6.6532780031620346828L19 -5.126482819920582625L-11) + -3.4107915379365690604L9) + +(my-assert + (* 3.3916052110984390742L19 1.2477416554656457027L-11) + 4.2318471007818771302L8) + +(my-assert + (* -2.0596546301412947634L18 1.4681903489886446838L-11) + -3.0239650502232254483L7) + +(my-assert + (* 5.4448198096650564945L18 -8.328351500006325204L-11) + -4.534637322908812735L8) + +(my-assert + (* -9.0101064221252591136L19 -8.313725422339249255L-11) + 7.4907550819604901853L9) + +(my-assert + (* 9.807792586975021252L19 -8.1013942555768171325L-11) + -7.9456794524008327797L9) + +(my-assert + (* -6.569928333884882197L17 1.8031274577764523257L19) + -1.1846418174451330701L37) + +(my-assert + (* 9.966374081256518232L19 1.1925741835931471136L18) + 1.1885640433338393863L38) + +(my-assert + (* -5.1958776350000747272L19 9.541066943279536452L19) + -4.957421634462466998L39) + +(my-assert + (* 3.0864687811444473814L19 -7.292720897062086383L17) + -2.2508755378381858676L37) + +(my-assert + (* -4.9023499593352016396L19 -7.837521201177228469L19) + 3.8422271741879966693L39) + +(my-assert + (* 1.1092141282192635266L19 -8.705681388875638857L19) + -9.656464792316359058L38) + +(my-assert + (* 9.719341608862581484L18 3.910223765755272544L-21) + 0.038004800546468552602L0) + +(my-assert + (* 9.0834836835472717744L19 2.3217130663560934873L-22) + 0.021089242756124079488L0) + +(my-assert + (* -8.9569500426805542816L19 -6.8114530414478270673L-22) + 0.061009844610312705923L0) + +(my-assert + (* -6.250871904307721917L18 -1.7897852706103755451L-21) + 0.01118771846280218958L0) + +(my-assert + (* -4.8350255195162635852L19 -5.4114390027140489403L-21) + 0.26164445675428065787L0) + +(my-assert + (* -3.787718813779143278L19 4.715777953310022763L-22) + -0.017862040875357275534L0) + +(my-assert + (* -9.6946973380533561685L-21 0.29842171245928506197L0) + -2.8931081813963549629L-21) + +(my-assert + (* -1.5138229787560283214L-21 -0.63587548364028950173L0) + 9.626029187622732088L-22) + +(my-assert + (* 6.9088409628577453984L-21 0.6675889882861618064L0) + 4.6122661486241942486L-21) + +(my-assert + (* -5.9331491274547789645L-21 0.1840021396402183602L0) + -1.0917121342561739605L-21) + +(my-assert + (* 6.5714942924276749333L-21 0.042451475976117785684L0) + 2.789696320821885891L-22) + +(my-assert + (* 8.381861494201174241L-21 -0.14355711097860731382L0) + -1.2032758207303532943L-21) + +(my-assert + (* 2.014342763215141127L-21 -1.2338457666735291661L9) + -2.4853882910224610282L-12) + +(my-assert + (* -5.670580024618139724L-21 -8.0192486381311308156L8) + 4.5473791139832611237L-12) + +(my-assert + (* -1.9225557816894129732L-21 7.9269598913745234357L9) + -1.5240022570382171054L-11) + +(my-assert + (* 4.0368254062037218916L-21 -9.5325393449487114215L8) + -3.848119701332554298L-12) + +(my-assert + (* 4.2776037356780859957L-21 -5.1221437260809706463L9) + -2.1910501137364030878L-11) + +(my-assert + (* -6.7334467986153699064L-21 -7.7745493828541701813L9) + 5.2349514652656512034L-11) + +(my-assert + (* -4.315187380180362795L-21 1.3410692406986483366L-11) + -5.786965063410868682L-32) + +(my-assert + (* 3.343397258359340776L-21 3.0757040339096610197L-12) + 1.0283300434498325547L-32) + +(my-assert + (* 8.5537743863632264L-21 7.5263454541513394514L-11) + 6.4378660968641032133L-31) + +(my-assert + (* -2.842610565794174946L-21 3.153716909493170071L-11) + -8.9647890084490369953L-32) + +(my-assert + (* 2.8400800161467519014L-22 2.0497242686367281441L-11) + 5.8213809339661880995L-33) + +(my-assert + (* 9.982896581447590365L-21 1.6568727649785948007L-11) + 1.654038946139843086L-31) + +(my-assert + (* 4.678227176611232891L-21 8.297236114758786796L19) + 0.38816355482824754693L0) + +(my-assert + (* -2.7181316933272033506L-21 -7.7081523870452907184L19) + 0.20951773300223540615L0) + +(my-assert + (* 3.755562697893016061L-21 -9.043255746258523336L19) + -0.33962513948155180184L0) + +(my-assert + (* -6.788248742851763723L-21 -2.3639021583849588926L19) + 0.16046755854881268057L0) + +(my-assert + (* -4.100847017987407598L-21 -3.6481227061862975968L19) + 0.14960393120916230025L0) + +(my-assert + (* -2.001548479939126796L-21 -8.705055796099425971L19) + 0.17423591196468091344L0) + +(my-assert + (* -3.670443367722997441L-21 3.6588667206894740936L-22) + -1.34296630883370731296L-42) + +(my-assert + (* -6.6783435670093499397L-22 -8.113066551196750321L-21) + 5.4181845810903550342L-42) + +(my-assert + (* 4.816859192586505112L-21 -1.1868626619923445382L-22) + -5.716950323755514841L-43) + +(my-assert + (* 4.6402358755296483015L-21 -4.244356902115351796L-22) + -1.9694817165747535215L-42) + +(my-assert + (* 9.3247068197076461794L-21 3.5271238356611001996L-21) + 3.288939568434245211L-41) + +(my-assert + (* 8.7860048755888267426L-21 7.187872989134290154L-21) + 6.315268712764710716L-41) + +;; ---- Test von FLOOR --- + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9677507664075728311L0 0.09829392666835353511L0)) + (-10 0.015188500275962520004L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.084596576622269801105L0 -0.78271578747309396924L0)) + (0 -0.084596576622269801105L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.97785517019559092334L0 -0.24687352093087197807L0)) + (-4 -0.009638913527896988987L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.36348468689259258175L0 0.5156866254701831051L0)) + (0 0.36348468689259258175L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.51463186192345608164L0 0.8683136279312965567L0)) + (-1 0.35368176600784047506L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.36128372948365635348L0 -0.5061584717303788097L0)) + (-1 -0.1448747422467224562L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.83188875677783952054L0 -6.988497329115560525L9)) + (0 -0.83188875677783952054L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.09110744229488624391L0 -9.792597852253288497L9)) + (0 -0.09110744229488624391L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.23616060202132526459L0 -1.5882829404848723914L9)) + (-1 -1.5882829402487117894L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.09652925723903261584L0 6.2261024177069773893L9)) + (-1 6.226102417610448132L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.5413601234707634158L0 9.144943549323542538L9)) + (0 0.5413601234707634158L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.57037258938648310115L0 4.436821091919698621L9)) + (-1 4.4368210913493260317L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.9973297751770725278L0 3.4051851548139874998L-11)) + (-29288562291 1.4506986275662661537L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.6604979952397203417L0 -4.3497555374342239963L-11)) + (-15184715315 -1.8114827519649365006L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.38589975187928444138L0 1.0289103184336123803L-12)) + (375056742036 3.5046726009323829848L-13)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.9402638162334174371L0 4.2262799834524861567L-11)) + (22248024738 1.7766010468098603481L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.8642082843541437474L0 8.911777256338402297L-11)) + (-9697373033 6.304376014060421794L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.7435773981922973139L0 5.910629837324535378L-11)) + (12580341159 1.1224045374678474888L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.7898063255151059068L0 1.2757118849664610875L18)) + (0 0.7898063255151059068L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.19544684487626281231L0 -3.6071314846523434156L19)) + (-1 -3.6071314846523434156L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.032130218136830583316L0 -3.367647816525978896L18)) + (0 -0.032130218136830583316L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.25693079625787854222L0 2.3815464531684079734L19)) + (-1 2.3815464531684079734L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -0.3975875412090936933L0 3.9957351306215043416L19)) + (-1 3.9957351306215043416L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.16223305219726616216L0 -5.3922124894358790612L19)) + (-1 -5.3922124894358790612L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.14869268750642991106L0 -4.676414410846522305L-21)) + (-31796302560686368198 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.4848921957991629974L0 7.275052251851656838L-21)) + (66651369504012501536 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.44996459510190342355L0 -3.96515259272563559L-21)) + (-113479767696052002376 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.7246909129638354568L0 -1.2540349367528059089L-21)) + (-577887339279675740320 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.83383904440522878455L0 3.5186204165781412753L-21)) + (236978970643311773536 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 0.26779759740636464572L0 -6.954613119627800336L-21)) + (-38506469418200611672 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.4845680268023566543L9 -0.2629469688312594538L0)) + (28464173061 -0.1240146549242767677L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.1612132433805581187L9 -0.09975641287987705455L0)) + (-61762578120 -0.083822638930812785824L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.6629628120558108524L9 0.35361739315194823028L0)) + (-10358548203 0.32784699422401302726L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.999024858613990497L9 -0.6086338795192380592L0)) + (11499564999 -0.48897756390533489348L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.2927999071819381092L9 -0.8483437666321241058L0)) + (-5060212707 -0.6341788853647631104L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.377925687006929662L9 0.3220507356662819166L0)) + (-13593900595 0.18712780555802854961L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.5387759396672939425L9 7.7154581598602048657L9)) + (-2 5.892140380053115789L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.64339842966998351L9 4.025489717604319313L9)) + (-2 2.4075810055386551162L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.811594948157823536L9 -7.834071766040306942L9)) + (0 -4.811594948157823536L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.4476035118893197435L9 3.0450117757143498866L9)) + (1 1.4025917361749698569L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.3465328576805684287L9 -4.603589573313564281L9)) + (1 -2.7429432843670041477L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.956277095163508632L9 -6.664438280281275845L9)) + (-1 -1.708161185117767213L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.367757792316331005L9 -7.8163461329531150714L-11)) + (-55879789840705743024 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.7778036898247465523L8 3.4933422750724630952L-11)) + (-13676883951274541565 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.667353710605079077L9 5.3863219342714070564L-11)) + (-123783052553596643928 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.6004002390836614547L9 -9.313678706634845693L-11)) + (70867811173061956036 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.439278803200832958L9 -6.7075776392225367144L-11)) + (140725598880953434976 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.207319097846486017L9 -5.7812820689283059893L-11)) + (159260852317369718528 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.564134292866958547L9 6.4508269927189105468L19)) + (-1 6.4508269919624971176L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.7520914080101070246L9 -4.4901662701989554116L17)) + (0 -5.7520914080101070246L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.801170739094381102L9 9.482698257311007893L19)) + (-1 9.482698256330890819L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.471594576665974082L8 3.1667053210759199935L18)) + (0 7.471594576665974081L8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.4762144691604037974L9 -8.2417624342716462896L19)) + (0 -6.4762144691604037974L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.5263312844382694187L9 9.5950716135522835064L19)) + (-1 9.5950716129996503776L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.1312033848911460338L9 -8.61316266389637687L-21)) + (-363537008074414891396807786496 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.6279029713558476835L9 -4.516664720059022692L-21)) + (-581823786849847663134534270976 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.502075635961923785L9 -9.685834626464620576L-21)) + (-464810293545679143271024033792 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.4031562604294053729L9 3.412866773725220897L-21)) + (411137132932332056394984325120 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.3024038761755407723L9 2.485284435684751149L-21)) + (-1731151498959165530746191347712 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.136473603422627364L9 5.6959828635137213127L-21)) + (1077333578850898685241017237504 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.202208473677937235L-11 0.12393605769441814725L0)) + (-1 0.123936057612396062516L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.6757073154686102475L-11 -0.37237633673270687662L0)) + (0 -8.675707315468610247L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.6028622390057924218L-11 0.6499341232771672055L0)) + (0 5.6028622390057924218L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.5783899320025937576L-11 -0.7229560019811405793L0)) + (-1 -0.7229560019353566799L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.224213822400873615L-11 -0.87051303270552073176L0)) + (-1 -0.87051303263327859354L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.5008008233955830292L-11 -0.45974678868400245752L0)) + (0 -5.5008008233955830295L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.949553569817051437L-11 -4.9088361621296460857L9)) + (0 -5.949553569817051437L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.068981360820356321L-11 3.9567179334666110438L9)) + (0 9.068981360820356321L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.4621680776088405294L-13 4.3691679646970805987L9)) + (0 3.4621680776088405294L-13)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.005939678622022073L-11 -9.2132271371400602936L8)) + (-1 -9.213227137140060293L8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.8015601712459487755L-11 -4.769849366969915586L9)) + (-1 -4.769849366969915586L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.736177705951390388L-11 8.3701230195943479203L9)) + (0 8.736177705951390388L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.8368349664293751446L-11 1.7247862508910726963L-11)) + (-6 1.5118825389170610328L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.0922301210797840822L-11 2.9157326021078492393L-11)) + (-1 8.235024810280651572L-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.929248815922456709L-11 -6.9934608623319373425L-11)) + (1 -2.9357879535905193665L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.809298490106908006L-11 2.521478295865126635L-11)) + (3 1.244863602511528101L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.3620267190952160604L-11 -5.0806267993123045533L-11)) + (-2 -2.7992268795293930463L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.070716461299934103L-11 1.372581158818204212L-11)) + (-7 5.3735165042749538097L-12)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.459630170957188741L-11 -3.429772398019229389L19)) + (0 -7.459630170957188741L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.9725650506989118904L-11 -1.7770668980460508816L19)) + (-1 -1.7770668980460508816L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.3974118251214889016L-12 -5.69117448017374684L19)) + (-1 -5.69117448017374684L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.080192761938897539L-11 5.1550284925054312868L19)) + (0 9.080192761938897539L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.694299339180548789L-11 3.1601030797220572842L19)) + (0 7.694299339180548789L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.5788554873601060938L-11 5.5699367746931070664L19)) + (0 5.5788554873601060938L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.087371164243010522L-11 1.7025318283693090775L-21)) + (-24007605005 1.5007203773756006028L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.3575974688385316083L-11 -1.6670029902289832508L-21)) + (44136678290 -1.8066891019200848581L-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.0850282868697332469L-11 5.7344803128377181472L-21)) + (1892112672 1.4425616831217755076L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.848519351300913193L-11 -7.121687974823219785L-21)) + (13828911609 -2.300608125189343731L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.0260591554314098406L-12 1.7303586387117179437L-22)) + (17488046048 9.689796116124082976L-23)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.867643793784483945L-11 2.9831220978672803306L-21)) + (19669472456 9.594326475082730988L-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.453252855247919707L19 0.3964594556008910194L0)) + (238441856328540902016 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.9865852464762410773L17 0.8745495786051183551L0)) + (227155245977568008 0.08198902299422984579L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.8003655986843771616L19 -0.57075967601329721915L0)) + (-101625357264188433960 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 6.5463855676706502812L19 0.5124698839969514896L0)) + (127741859026189966704 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.053368905864221505L19 0.40679331708739617821L0)) + (197972006116659527920 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.5722362029533885376L19 0.1793174966141533504L0)) + (478047952085719142240 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.6056603867132043536L19 1.8364346532401849241L9)) + (-35970026895 8.274070785684816422L8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.473965171745108034L19 5.5749126908032718576L9)) + (4437675186 5.356910410798194379L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.405924011882179756L19 -6.4568556406242929674L9)) + (6823637165 -4.1798826632701602209L8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.1093676314099077168L19 5.727620773112868108L8)) + (36827990451 1.8408274540307780489L8)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.0962340119185741432L19 -8.173187675545835245L9)) + (1341256380 -4.422519927692124746L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.664836922872330681L19 -4.5461452948374001435L9)) + (21259410546 -4.0088028420210172099L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.9654629946168490416L19 -6.27691916031617149L-11)) + (-1587636026543136775574879469568 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.2700534905234296955L19 -7.6392648594402208417L-11)) + (166253365198349054807791108096 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.837735447773461618L18 -8.6041613252133785413L-11)) + (91092381366746282195935035392 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.849306367034469812L19 -8.744903371098252931L-11)) + (-554529439749024491444258209792 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.3895751736590951245L18 -8.9218106166526971406L-11)) + (71617471477514379195326660608 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.1249006547358954392L19 -3.749899421128778124L-11)) + (299981553744522252727485464576 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.8298889769606521412L19 3.2897859420995047714L19)) + (-2 1.7496829072383574016L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.618272569239742257L19 -2.4246730847406800364L19)) + (3 -3.4425331501770214745L18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.9344217376670949096L19 -2.187787768895506888L19)) + (4 -1.1832706620850673572L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.9222824564168688912L19 -9.476307993509074433L19)) + (-1 -5.5540255370922055412L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -2.012988112115775752L19 -1.01146191266402097525L18)) + (19 -9.1210478054135899006L17)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.6136075623649245696L19 -9.374471951386232653L19)) + (-1 -7.6086438902130808345L18)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.0954879593227223964L19 3.4785793369902262412L-21)) + (-11773449913223093127289481096658923028480 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.7633820540313762628L19 -6.9799216943629666126L-21)) + (8257086979479904139315172946770002968576 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -4.5945941433359568196L19 -9.26874309885338918L-21)) + (4957084357969034092339972319162935541760 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.069653875532044557L19 1.1607862998892810815L-21)) + (78133708817868823323292026086376001765376 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.9663881236128118596L19 -7.53224056983834607L-21)) + (-2610628411799403924128603371383036051456 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.8155182638858600344L19 -9.78280482738867461L-21)) + (-3900229362854759958152852242692868931584 0.0L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 2.0785751397779279812L-21 0.84874462118484074924L0)) + (0 2.0785751397779279812L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.468679817093889512L-22 -0.14230041428757812886L0)) + (-1 -0.14230041428757812886L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.5329587582370771722L-21 -0.75145077780984780047L0)) + (0 -3.5329587582370771722L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.0147425004279850959L-21 0.55049889413410685307L0)) + (0 1.0147425004279850959L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -9.214176537319943048L-21 -0.45008902557926736644L0)) + (0 -9.214176537319943048L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.146684367801419132L-21 0.3317375182580383851L0)) + (-1 0.3317375182580383851L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.8958965362796452575L-23 -8742129.925142999928L0)) + (-1 -8742129.925142999928L0)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -8.629925553125559817L-22 1.4904768761159059732L9)) + (-1 1.4904768761159059732L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.7636696713810751494L-21 1.2803675755746476424L9)) + (-1 1.2803675755746476424L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.8572218293550540256L-21 7.311951574932556098L9)) + (0 7.8572218293550540256L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.8831628670454666175L-21 -2.430599936529262355L9)) + (-1 -2.430599936529262355L9)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.891885696934149925L-21 6.0077688200842341403L9)) + (0 5.891885696934149925L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.5378511525885539255L-21 -4.317564477957860586L-11)) + (0 -5.5378511525885539255L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.9525004120740256159L-21 9.454884961900014292L-11)) + (-1 9.454884961704764251L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 5.461359828153347278L-21 -9.7061135180917529105L-11)) + (-1 -9.706113517545616928L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 9.644530490453124287L-21 8.28693431641614359L-11)) + (0 9.644530490453124287L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 8.997549905605484822L-21 5.2672865249640494307L-11)) + (0 8.997549905605484822L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -1.55338435917637846L-21 5.9708770769690056966L-11)) + (-1 5.9708770768136672606L-11)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.9285675924255819076L-21 5.674913585946206864L19)) + (0 3.9285675924255819076L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.6185336116295331734L-21 -9.043926006483480333L19)) + (0 -3.6185336116295331734L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.32672036508508268L-21 1.205614654464109627L19)) + (-1 1.205614654464109627L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -3.3565132746900103151L-21 8.585503247975515849L19)) + (-1 8.585503247975515849L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.9204354176156616745L-21 -3.6158709669328356396L19)) + (0 -6.9204354176156616745L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -7.5176747956103960436L-21 9.3440027997860057096L19)) + (-1 9.3440027997860057096L19)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -6.302622462978502841L-21 8.1107309029375862425L-21)) + (-1 1.8081084399590834014L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 1.4803054325001667241L-22 6.3345497995208400772L-21)) + (0 1.4803054325001667241L-22)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR -5.7089861270321677843L-21 9.540482421100450586L-21)) + (-1 3.831496294068282802L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 3.3765199428161524112L-21 9.669802014415968729L-21)) + (0 3.3765199428161524112L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 7.52101063082155294L-21 8.827949370572986921L-21)) + (0 7.52101063082155294L-21)) + +(my-assert + (MULTIPLE-VALUE-LIST (FLOOR 4.196504310402249954L-23 3.785428476220113075L-21)) + (0 4.196504310402249954L-23)) + +;; ---- Test von / --- + +(my-assert + (/ 0.8476517865511829377L0 0.14598720922015648169L0) + 5.8063428370144327317L0) + +(my-assert + (/ -0.16515392772872533974L0 0.2885771921352848653L0) + -0.5723041606534907598L0) + +(my-assert + (/ -0.25791761734650428572L0 -0.17472849542471660309L0) + 1.4761050664322265015L0) + +(my-assert + (/ -0.9418668871216534004L0 -0.25801526180943099573L0) + 3.6504309106230792821L0) + +(my-assert + (/ -0.25726582509610465451L0 0.7704327058756196045L0) + -0.33392381078074095957L0) + +(my-assert + (/ -0.021409432992321506645L0 -0.44293479613874918959L0) + 0.048335405524597819813L0) + +(my-assert + (/ -0.26771090178828336857L0 -7.7011892538310270067L9) + 3.4762280599078659542L-11) + +(my-assert + (/ 0.82867609196336006595L0 -3.0042819216966844948L9) + -2.7583166745395210866L-10) + +(my-assert + (/ 0.40732354689187331287L0 -7.559832309976744222L9) + -5.387997116739304149L-11) + +(my-assert + (/ -0.53349543673778000914L0 -5.104278761341346705L8) + 1.045192595628502556L-9) + +(my-assert + (/ 0.17669669311850475256L0 -9.181879875841464834L9) + -1.9244064996255633173L-11) + +(my-assert + (/ -0.38525727576606363245L0 -4.8936643582468263693L9) + 7.872572525674472248L-11) + +(my-assert + (/ 0.028580272067667963345L0 -7.9841173999044091L-11) + -3.5796407587907142282L8) + +(my-assert + (/ 0.72167998280372380157L0 -3.6437273419914776347L-12) + -1.980609181391958688L11) + +(my-assert + (/ -0.5863461999919387516L0 7.881986348526466578L-11) + -7.4390664239294943926L9) + +(my-assert + (/ 0.54541403791059564303L0 -2.6107257402815120583L-11) + -2.089128051619026705L10) + +(my-assert + (/ 0.7985324354238058011L0 9.752737902348257611L-12) + 8.187777047012979847L10) + +(my-assert + (/ 0.14104671220162837288L0 -1.679932803469743255L-11) + -8.3959734526470136372L9) + +(my-assert + (/ 0.84226961154302812054L0 -3.7790325979515268584L19) + -2.2287968936801211454L-20) + +(my-assert + (/ -0.17023320737807742781L0 -7.0544793122604881768L19) + 2.4131222141684768152L-21) + +(my-assert + (/ 0.51147038234753495475L0 7.2890488826322506176L19) + 7.01697012303244035L-21) + +(my-assert + (/ 0.15424860911694467965L0 -9.2121691156562017736L19) + -1.6744005367291526718L-21) + +(my-assert + (/ 0.18043991101271504866L0 -1.5135729370916590423L19) + -1.1921454631676461953L-20) + +(my-assert + (/ -0.8669749687756526617L0 8.7133495928438747096L19) + -9.949961946754488136L-21) + +(my-assert + (/ -0.6448505560111598971L0 3.636469578348857873L-21) + -1.7732873659951112376L20) + +(my-assert + (/ -0.81857582399766609004L0 5.2916132942068490006L-21) + -1.546930545536701092L20) + +(my-assert + (/ 0.77524450276763022L0 -7.652595302708246449L-21) + -1.0130478250865714831L20) + +(my-assert + (/ 0.627858729575384142L0 9.627326573065363056L-21) + 6.5216311590796329432L19) + +(my-assert + (/ -0.42943946308533227006L0 -2.2414950519882640498L-21) + 1.9158617490786266339L20) + +(my-assert + (/ -0.34220208112358558038L0 -7.4545803279812700505L-21) + 4.5904942473972275588L19) + +(my-assert + (/ 5.560943842255079481L9 -0.55841023848214400133L0) + -9.958527725728472542L9) + +(my-assert + (/ -8.661678305761957921L9 -0.87958882986448744696L0) + 9.847417351919312785L9) + +(my-assert + (/ 3.6954900583503502368L9 -0.36989453222048823558L0) + -9.9906587863470431315L9) + +(my-assert + (/ 6.740385471899914443L8 -0.2745720588185960522L0) + -2.454869406924301959L9) + +(my-assert + (/ -5.1381279403866914758L9 -0.32555782051482221485L0) + 1.578253574821668073L10) + +(my-assert + (/ -3.2065087686035281697L9 0.50505516522796299416L0) + -6.3488287802308291444L9) + +(my-assert + (/ -7.7979994067331648055L9 -6.4459990751639263853L9) + 1.2097425574847536075L0) + +(my-assert + (/ -4.7272619195621447717L9 -3.825695015629283172L8) + 12.356609453314103588L0) + +(my-assert + (/ -3.5376744034596315073L9 2.7483444719369282795L9) + -1.2872019645217230068L0) + +(my-assert + (/ -2.2400216393287578975L9 -3.7058330823204350567L9) + 0.6044583200509807153L0) + +(my-assert + (/ 3.0621742151056386386L9 -8.846101104908494769L9) + -0.34616088814613589822L0) + +(my-assert + (/ 7.5149875074517868906L9 4.423024956398348232L9) + 1.6990606161017937287L0) + +(my-assert + (/ 7.6970261502618782055L9 -9.7716080626747355186L-11) + -7.876928854384493259L19) + +(my-assert + (/ -8.725835744855911806L8 8.409822932470646079L-11) + -1.0375766309139670758L19) + +(my-assert + (/ 5.820797723708174118L9 -2.882166534035175912L-11) + -2.0195910454760464445L20) + +(my-assert + (/ 1.207852991950790034L9 5.840354579417081103L-11) + 2.068115857567237665L19) + +(my-assert + (/ 3.1046967393071541823L9 -5.5642977043818474125L-11) + -5.5796740294147564416L19) + +(my-assert + (/ 4.392532668212736406L9 -7.535498815249885942L-11) + -5.8291199771983175508L19) + +(my-assert + (/ 1.3280881496906639524L9 -1.766515912740190632L19) + -7.518121632035316941L-11) + +(my-assert + (/ 1.4277961930808139626L9 -8.986506745304867108L19) + -1.5888222571321021114L-11) + +(my-assert + (/ -7.9134656119390343763L9 -3.4095849226963530828L19) + 2.3209469162249057589L-10) + +(my-assert + (/ -8.7882725472722691335L9 -5.186325400713441962L19) + 1.6945085138821670647L-10) + +(my-assert + (/ 3.8930727351090315925L9 -7.3980221641298868864L19) + -5.2623155875161027887L-11) + +(my-assert + (/ 9.998404421166073569L9 -8.1317115085820412065L18) + -1.2295571984586471158L-9) + +(my-assert + (/ 4.623792381028250544L9 6.996281129080973142L-21) + 6.6089287947690416075L29) + +(my-assert + (/ 8.472924939037688662L9 -4.3460987737519244214L-22) + -1.9495472560839050376L31) + +(my-assert + (/ 1.9551595642940545935L9 -7.5324972045717692564L-21) + -2.5956326450508222435L29) + +(my-assert + (/ -8.5478772651240992225L9 -2.4212066230883777513L-21) + 3.5304204042779411337L30) + +(my-assert + (/ 6.881700625121950854L9 -8.203099619911879591L-21) + -8.389146717684109215L29) + +(my-assert + (/ 6.097099876947129031L9 -4.76850418677518328L-21) + -1.2786189627046213921L30) + +(my-assert + (/ -5.0358061432469478737L-11 -0.6780392915138573621L0) + 7.427012278305451381L-11) + +(my-assert + (/ -1.49762284327640383L-11 0.15227257119521089694L0) + -9.835145171066142436L-11) + +(my-assert + (/ -7.1678035946969115934L-11 0.75360681415553320054L0) + -9.511330656861051013L-11) + +(my-assert + (/ 4.583894304978394541L-12 0.68934670181533335835L0) + 6.6496210004445016106L-12) + +(my-assert + (/ -3.8885547056166489716L-12 -0.010643810658165133798L0) + 3.6533482513930678043L-10) + +(my-assert + (/ 9.49880444227161124L-11 -0.122629749019578004226L0) + -7.745921783428843474L-10) + +(my-assert + (/ 2.1990660545226500317L-11 -1.4161745224867819854L9) + -1.552821364602098501L-20) + +(my-assert + (/ 9.951737846856727225L-11 -6.0164204240154494783L9) + -1.6540961477912788069L-20) + +(my-assert + (/ -5.873282338412930208L-11 2.3788798751415933107L9) + -2.4689276662460085614L-20) + +(my-assert + (/ 2.2209512664584027642L-11 5.1944018613813348683L9) + 4.2756631576205975403L-21) + +(my-assert + (/ -6.722318330051584872L-11 6.7936247801916195024L9) + -9.895039169151724367L-21) + +(my-assert + (/ -7.528877773200399613L-12 -9.535757813603057891L9) + 7.89541630604357328L-22) + +(my-assert + (/ -2.0857643618410047184L-11 2.701544718271986855L-11) + -0.77206360780699598463L0) + +(my-assert + (/ 2.5510439626733908612L-11 1.6734405694946451074L-11) + 1.5244305708709866576L0) + +(my-assert + (/ 3.048460642905138835L-11 5.1568899955161432057L-11) + 0.5911432366321058725L0) + +(my-assert + (/ 9.876491787625061464L-12 8.667781903943973216L-11) + 0.113944858062604306884L0) + +(my-assert + (/ 1.1166642175553123016L-11 -7.759981600144040302L-11) + -0.14390036923986841014L0) + +(my-assert + (/ -2.7282824760136843772L-11 -9.160281916489131182L-11) + 0.2978382653379466574L0) + +(my-assert + (/ -3.1587174777348029438L-11 -4.9090150171793744104L19) + 6.4345239659701453497L-31) + +(my-assert + (/ -4.512784364891002838L-11 5.9600731551720265308L19) + -7.571692909465218857L-31) + +(my-assert + (/ -1.431681316436341718L-11 -4.22349605246125618L19) + 3.3898014788057508284L-31) + +(my-assert + (/ -6.719040537613210677L-11 -4.545488183802435408L19) + 1.47817797911258332435L-30) + +(my-assert + (/ 2.5092238442261623676L-11 3.3004591427193857704L19) + 7.602650830449936487L-31) + +(my-assert + (/ -6.198495042920933878L-12 1.8747110273916984954L19) + -3.306373596972410786L-31) + +(my-assert + (/ 8.3326031863190006605L-11 6.3679312781687389584L-21) + 1.3085259281747860217L10) + +(my-assert + (/ 2.228308172351851791L-11 -4.6204647093882084617L-22) + -4.822692764700068564L10) + +(my-assert + (/ 9.7676469315043868665L-11 -6.6370355345926113967L-21) + -1.4716882078745621587L10) + +(my-assert + (/ -8.9713798012161717115L-11 -3.669192301028840519L-21) + 2.445055768459069116L10) + +(my-assert + (/ 7.214258511983827207L-11 -1.5195990661514104949L-21) + -4.7474749574931692373L10) + +(my-assert + (/ 1.4822028144092954099L-12 2.269595713994387529L-21) + 6.530690929974856047L8) + +(my-assert + (/ -4.6354687290142894644L19 0.032331325634476806982L0) + -1.4337391486574910728L21) + +(my-assert + (/ -2.389352438897577318L19 0.8660312577952003013L0) + -2.7589678979723536864L19) + +(my-assert + (/ -2.4109458405628950432L19 0.26688102636777617506L0) + -9.0337851040803631776L19) + +(my-assert + (/ 8.961066349333904704L19 -0.66178143682771294813L0) + -1.35408245844568974384L20) + +(my-assert + (/ 6.6419769467305502364L19 -0.8456142496793601811L0) + -7.854618047471472417L19) + +(my-assert + (/ 3.7389082257286159308L19 0.56261989685796304976L0) + 6.645531462021022254L19) + +(my-assert + (/ 7.814283695666500025L19 -4.6620013293904720047L9) + -1.6761650509199167363L10) + +(my-assert + (/ 6.6434731737611309404L19 -2.858805223329136325L9) + -2.323863521567472329L10) + +(my-assert + (/ -1.3409334390407788129L19 6.1497605350647401055L9) + -2.1804644772671013651L9) + +(my-assert + (/ 7.0858597943822241668L19 -2.58410378455919273L9) + -2.7420956684179617314L10) + +(my-assert + (/ -6.6455998228898640428L19 -7.7545004942277582046L9) + 8.569990843171226794L9) + +(my-assert + (/ 2.9602494058183339616L19 -5.7169856186590364077L9) + -5.1779899465842692843L9) + +(my-assert + (/ -6.698311323164055808L19 -6.553232827426109497L-11) + 1.02213846197113193186L30) + +(my-assert + (/ -7.554561034956199475L19 6.4764910162760040714L-11) + -1.1664589692120175174L30) + +(my-assert + (/ 6.7796490729162210612L19 9.9915237995070190003L-11) + 6.785400514434773617L29) + +(my-assert + (/ -6.9067747658009050975L18 -2.5761632749585983355L-11) + 2.681031452058062687L29) + +(my-assert + (/ 1.629413698021581386L19 -8.612780517302459862L-11) + -1.8918555915226283107L29) + +(my-assert + (/ 8.8732593909692189064L19 -4.0536919536865455935L-12) + -2.1889328277398133904L31) + +(my-assert + (/ 4.8426213700963381164L19 7.883038261101094331L19) + 0.61430900240485778846L0) + +(my-assert + (/ -5.2968355222513127376L19 1.5071497411718048594L19) + -3.5144719715328600349L0) + +(my-assert + (/ -6.2610887651422622925L18 1.0358424497888766788L19) + -0.60444411854509194816L0) + +(my-assert + (/ -2.4670994205369878408L19 6.9747461294856021948L19) + -0.3537188844920639511L0) + +(my-assert + (/ 6.9460731069354980812L19 3.1486762233902586798L19) + 2.2060296499639734035L0) + +(my-assert + (/ 8.8228286449463631936L19 6.7354354317536527728L19) + 1.3099121406987093833L0) + +(my-assert + (/ 3.2098388728662261428L19 -2.6305167886064038438L-21) + -1.2202312818412901165L40) + +(my-assert + (/ -7.144492994496515916L19 -2.0335028635662185032L-21) + 3.5133921483478965099L40) + +(my-assert + (/ -6.3695870249569899508L19 1.9319318539671607067L-21) + -3.2970039869042198792L40) + +(my-assert + (/ -5.4056057590545112688L19 6.6371220252553042967L-21) + -8.144502599899959829L39) + +(my-assert + (/ -4.5534797093596626272L19 9.223324048915255164L-21) + -4.9369182793650108047L39) + +(my-assert + (/ 3.9206183123968272208L19 -1.6559061178638737343L-21) + -2.3676573629998072004L40) + +(my-assert + (/ -8.768637785982664131L-21 -0.18184176456694917492L0) + 4.8221253279547290195L-20) + +(my-assert + (/ 2.6823352573966718016L-21 -0.55524799130252431824L0) + -4.830877912956219511L-21) + +(my-assert + (/ -4.0350541003620172524L-21 0.27000304046926068644L0) + -1.4944476526446376082L-20) + +(my-assert + (/ 6.332356861830292899L-21 0.65544003241974460534L0) + 9.6612299350294242524L-21) + +(my-assert + (/ 3.5603120340723305693L-21 -0.124100556644984066966L0) + -2.86889288035778711L-20) + +(my-assert + (/ 5.5961094005028721084L-21 0.47201702367299511838L0) + 1.18557363820414998006L-20) + +(my-assert + (/ 1.7187188076305931646L-21 8.3685668129856246863L9) + 2.0537791548292745125L-31) + +(my-assert + (/ -2.7220241842791803757L-21 2.2892422122227956846L9) + -1.1890503196846804849L-30) + +(my-assert + (/ -6.028203796038167925L-21 -5.415224539645905615L9) + 1.1131955382282900156L-30) + +(my-assert + (/ 6.6310444174308960725L-21 9.461342958972558645L9) + 7.0085657460946591684L-31) + +(my-assert + (/ -8.8033709586752979635L-21 2.8098765759657792274L9) + -3.1330098389284241575L-30) + +(my-assert + (/ -3.4027974212452472475L-21 6.219628754500815959L8) + -5.4710619484849846614L-30) + +(my-assert + (/ 8.388977931970215088L-21 2.8213325814913435694L-11) + 2.9734097947204223302L-10) + +(my-assert + (/ -9.3496400462478483586L-21 -9.381494249123695733L-11) + 9.966045704415559596L-11) + +(my-assert + (/ -6.936639418470504025L-21 5.6618206553549859367L-11) + -1.2251605694909792675L-10) + +(my-assert + (/ -2.3667892015182913211L-21 -7.1545639578577691874L-11) + 3.3080830857887236957L-11) + +(my-assert + (/ -9.576766108065157562L-21 -6.4350290609494113365L-11) + 1.4882242204905008798L-10) + +(my-assert + (/ -2.5955914883538434001L-22 5.8091383646322322124L-11) + -4.4681178609147595716L-12) + +(my-assert + (/ -2.9619491950657497217L-21 -5.3730670726011346488L19) + 5.512585558757694777L-41) + +(my-assert + (/ 2.5726455340193007026L-22 3.0037766865540527038L19) + 8.564703047118500122L-42) + +(my-assert + (/ -2.8277317971003367574L-21 -4.4068191966128705184L19) + 6.4167184332721487087L-41) + +(my-assert + (/ 7.503784949731224261L-21 5.9540210967055505192L19) + 1.2602886062804146604L-40) + +(my-assert + (/ 1.4876876016319254574L-22 8.6818746213386148185L18) + 1.7135557313571827969L-41) + +(my-assert + (/ 2.699544264870480357L-21 3.6796341400587007856L19) + 7.3364474893892979093L-41) + +(my-assert + (/ -7.285812539718203862L-21 5.700589904684711396L-21) + -1.2780804551000530294L0) + +(my-assert + (/ 3.6474102791520560028L-21 -6.343773677116707765L-21) + -0.574959080319812269L0) + +(my-assert + (/ -4.2510720089860863712L-21 -8.281980897162330288L-21) + 0.51329169455614642465L0) + +(my-assert + (/ 5.770684998505203844L-21 6.5700291863604419324L-21) + 0.8783347584642853315L0) + +(my-assert + (/ -4.8018196973750014744L-21 -7.3250029580209059804L-21) + 0.6555382605159211192L0) + +(my-assert + (/ -3.9261100835261094614L-21 -8.986577968334144672L-21) + 0.436885997913830856L0) diff --git a/src/ansi-tests/number2.lisp b/src/ansi-tests/number2.lisp new file mode 100644 index 000000000..89985d27a --- /dev/null +++ b/src/ansi-tests/number2.lisp @@ -0,0 +1,35 @@ +;;; based on v1.4 -*- mode: lisp -*- +(in-package :user) + +(my-assert + (gcd 2346026393680644703525505657 17293822570713318399) + 11) + +(my-assert + (multiple-value-list (xgcd 77874422 32223899)) + (1 -9206830 22249839)) + +(my-assert + (multiple-value-list (xgcd 560014183 312839871)) + (1 77165803 -138134388)) + +(my-assert + (multiple-value-list (xgcd 3 2)) + (1 1 -1)) + +(my-assert + (multiple-value-list (xgcd 2 3)) + (1 -1 1)) + +(my-assert + (let ((a 974507656412513757857315037382926980395082974811562770185617915360) + (b -1539496810360685510909469177732386446833404488164283)) + (multiple-value-bind (g u v) (xgcd a b) + (and (eql g 1) (eql g (+ (* a u) (* b v)))) + ) ) + T) + +(my-assert + (isqrt #x3FFFFFFFC000000000007F) + #x7FFFFFFFBFF) + diff --git a/src/ansi-tests/path.lisp b/src/ansi-tests/path.lisp new file mode 100644 index 000000000..9fb9048f7 --- /dev/null +++ b/src/ansi-tests/path.lisp @@ -0,0 +1,583 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (setf string "test-pathname.abc" symbol 'test-pathname.abc) + test-pathname.abc) + +;;pathname -mögl. Argumenttypen: pathname,string,symbol,stream +;; -resultat: pathname + +(my-assert + (SETF PATHSTRING (PATHNAME STRING)) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" + TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +(my-assert + (SETF PATHSYMBOL (PATHNAME symbol)) + #+XCL + #S(PATHNAME SYSTEM::HOST + NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME + "TEST-PATHNAME" TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +(my-assert + (SETF PATHPATH (PATHNAME PATHSYMBOL)) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" + TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +(my-assert + (SETF STREAM (OPEN STRING :DIRECTION :OUTPUT) + a nil) + nil) + +;; (SETF PATHSTREAM (PATHNAME STREAM)) +;; "test-pathname.lsp" + +(my-assert + (MAPCAR (FUNCTION PATHNAMEP) + (LIST PATHSTRING PATHSYMBOL PATHPATH ;PATHSTREAM + )) + (T T T ;T + )) + + +;; funktion truename liefert filename fuer pathname oder stream +;; einen Pfadnamen +;; +;; (MAPCAR (FUNCTION TRUENAME) (LIST PATHSTRING PATHSYMBOL PATHPATH STREAM +;; ;PATHSTREAM +;; )) +;; ERROR + + + +(my-assert + (PARSE-NAMESTRING STRING) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" + TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +(my-assert + (PARSE-NAMESTRING SYMBOL) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" + TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +#+XCL + +(my-assert + (PARSE-NAMESTRING "bab:test-pathname.abc") + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "$1$DUA70" DIRECTORY "43.BABYLON.REL2" SYSTEM::NAME + "TEST-PATHNAME" TYPE "ABC" SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "bab:test-pathname.abc;3") + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "$1$DUA70" DIRECTORY "43.BABYLON.REL2" SYSTEM::NAME + "TEST-PATHNAME" TYPE "ABC" SYSTEM::VERSION 3)) + +(my-assert + (PARSE-NAMESTRING PATHSTRING) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE + "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" TYPE "ABC" + SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +(my-assert + (PARSE-NAMESTRING "test-pathname.abc" NIL) + #+XCL + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST-PATHNAME" + TYPE "ABC" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "test-pathname" :TYPE "abc" :VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "sirius::disk00$abt43:[heicking]test-pathname.abc") + #S(PATHNAME + SYSTEM::HOST "SIRIUS" SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "HEICKING" + SYSTEM::NAME "TEST-PATHNAME" TYPE "ABC" SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "sirius::disk00$abt43:[heicking]test-pathname.abc" "sirius") + #S(PATHNAME + SYSTEM::HOST "SIRIUS" SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "HEICKING" + SYSTEM::NAME "TEST-PATHNAME" TYPE "ABC" SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "sirius::disk00$abt43:[heicking]test-pathname.abc" "orion") + ERROR) + +(my-assert + (PARSE-NAMESTRING "abc.123" NIL NIL :START 0 :END 5) + #+XCL + #S(PATHNAME SYSTEM::HOST + NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "ABC" TYPE + "1" SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "abc" :TYPE "1" :VERSION NIL)) + +(my-assert + (PARSE-NAMESTRING "abc.123" NIL NIL :START 2 :END 5) + #+XCL + #S(PATHNAME SYSTEM::HOST + NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "C" TYPE "1" + SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME "c" :TYPE "1" :VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon" NIL NIL :START 0 :END 3) + #S(PATHNAME SYSTEM::HOST + NIL SYSTEM::DEVICE "$1$DUA70" DIRECTORY "43.BABYLON.REL2" SYSTEM::NAME NIL TYPE + NIL SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon" NIL NIL :START 0 :END 7) + #S(PATHNAME SYSTEM::HOST + NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "BABYLON" + TYPE NIL SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon" NIL *DEFAULT-PATHNAME-DEFAULTS* :START 0 :END 7) + #S(PATHNAME + SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME + "BABYLON" TYPE NIL SYSTEM::VERSION NIL)) + +(my-assert + *DEFAULT-PATHNAME-DEFAULTS* + #+XCL + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE NIL + DIRECTORY NIL SYSTEM::NAME NIL TYPE "lsp" SYSTEM::VERSION :NEWEST) + #+(and CLISP (or win32 os2)) + #S(PATHNAME :HOST NIL :DEVICE "C" :DIRECTORY (:RELATIVE) + :NAME NIL :TYPE NIL :VERSION NIL) + #+(and CLISP unix) + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME NIL :TYPE NIL :VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon" NIL *DEFAULT-PATHNAME-DEFAULTS* :START 0 :END 3) + #S(PATHNAME + SYSTEM::HOST NIL SYSTEM::DEVICE "$1$DUA70" DIRECTORY "43.BABYLON.REL2" + SYSTEM::NAME NIL TYPE NIL SYSTEM::VERSION NIL)) + +;; (PARSE-NAMESTRING "babylon.c.c" NIL NIL :JUNK-ALLOWED T) +;; #S(PATHNAME +;; SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME +;; "BABYLON" TYPE "C" SYSTEM::VERSION NIL) + +;; (PARSE-NAMESTRING "babylon;c.c" NIL NIL :JUNK-ALLOWED T) +;; #S(PATHNAME +;; SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME +;; "BABYLON" TYPE NIL SYSTEM::VERSION NIL) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon;c.c" NIL NIL :JUNK-ALLOWED NIL) + ERROR) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon.c.c" NIL NIL :JUNK-ALLOWED NIL) + ERROR) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon.c;c" NIL NIL :JUNK-ALLOWED NIL) + ERROR) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon.c;" NIL NIL :JUNK-ALLOWED NIL) + #S(PATHNAME + SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME + "BABYLON" TYPE "C" SYSTEM::VERSION NIL)) + +#+XCL +(my-assert + (PARSE-NAMESTRING "babylon.c;5" NIL NIL :JUNK-ALLOWED NIL) + #S(PATHNAME + SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME + "BABYLON" TYPE "C" SYSTEM::VERSION 5)) + +;; (MERGE-PATHNAME "test$$" SYMBOL 10) ERROR +;; +;; (MERGE-PATHNAME "test$$" SYMBOL) ERROR +;; +;; (MERGE-PATHNAME "test$$" PATH) ERROR +;; +;; (MERGE-PATHNAME "test$$") ERROR + +#+XCL +(my-assert + (MERGE-PATHNAMES "test$$") + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE + "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST$$" TYPE "lsp" + SYSTEM::VERSION :NEWEST)) + +#+XCL +(my-assert + (MERGE-PATHNAMES "test$$" SYMBOL) + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE + "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST$$" TYPE "ABC" + SYSTEM::VERSION :NEWEST)) + +#+XCL +(my-assert + (MERGE-PATHNAMES "test$$" SYMBOL 2) + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST$$" TYPE + "ABC" SYSTEM::VERSION 2)) + +#+XCL +(my-assert + (MERGE-PATHNAMES "test$$" (PATHNAME SYMBOL) 2) + #S(PATHNAME SYSTEM::HOST NIL + SYSTEM::DEVICE "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST$$" TYPE + "ABC" SYSTEM::VERSION 2)) + +#+XCL +(my-assert + (MERGE-PATHNAMES "test$$" STREAM 2) + #S(PATHNAME SYSTEM::HOST 16 SYSTEM::DEVICE + "DISK00$ABT43" DIRECTORY "XCL.MAIN" SYSTEM::NAME "TEST$$" TYPE :ESCAPE + SYSTEM::VERSION 2)) + + +;; (MERGE-PATHNAME STRING SYMBOL) ERROR + +#+XCL +(my-assert + (MAKE-PATHNAME :NAME "a" :HOST (QUOTE ORION)) + #S(PATHNAME SYSTEM::HOST ORION + SYSTEM::DEVICE NIL DIRECTORY NIL SYSTEM::NAME "a" TYPE NIL SYSTEM::VERSION + :NEWEST)) + +#+XCL +(my-assert + (DEFMACRO TEST (&REST BODY) (\` (APPLY (FUNCTION MAKE-PATHNAME) (\,@ BODY)))) + TEST) + +#+XCL +(my-assert + (setf a '(:host "sirius" :name "a")) + (:host "sirius" :name "a")) + +#+XCL +(my-assert + (TEST A) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE NIL DIRECTORY NIL + SYSTEM::NAME "a" TYPE NIL SYSTEM::VERSION :NEWEST)) + +#+XCL +(my-assert + (SETF A (LIST* :DEVICE "disk00$abt43" A)) + (:DEVICE "disk00$abt43" :HOST "sirius" :NAME "a")) + +#+XCL +(my-assert + (TEST A) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE "disk00$abt43" + DIRECTORY NIL SYSTEM::NAME "a" TYPE NIL SYSTEM::VERSION :NEWEST)) + +#+XCL +(my-assert + (SETF A (LIST* :DIRECTORY "[heicking.comlisp]" A)) + (:DIRECTORY + "[heicking.comlisp]" :DEVICE "disk00$abt43" :HOST "sirius" :NAME "a")) + +#+XCL +(my-assert + (TEST A) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE "disk00$abt43" + DIRECTORY "[heicking.comlisp]" SYSTEM::NAME "a" TYPE NIL SYSTEM::VERSION + :NEWEST)) + +#+XCL +(my-assert + (SETF A (LIST* :TYPE "raf" A)) + (:TYPE "raf" :DIRECTORY "[heicking.comlisp]" + :DEVICE "disk00$abt43" :HOST "sirius" :NAME "a")) + +#+XCL +(my-assert + (TEST A) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE "disk00$abt43" + DIRECTORY "[heicking.comlisp]" SYSTEM::NAME "a" TYPE "raf" SYSTEM::VERSION + :NEWEST)) + +#+XCL +(my-assert + (SETF A (LIST* :VERSION 3 A)) + (:VERSION 3 :TYPE "raf" :DIRECTORY + "[heicking.comlisp]" :DEVICE "disk00$abt43" :HOST "sirius" :NAME "a")) + +#+XCL +(my-assert + (TEST A) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE "disk00$abt43" + DIRECTORY "[heicking.comlisp]" SYSTEM::NAME "a" TYPE "raf" SYSTEM::VERSION 3)) + +(my-assert + (MAPCAR (FUNCTION PATHNAMEP) (LIST PATHSYMBOL PATHPATH PATHSTRING)) + (T T T)) + +#+XCL +(my-assert + (SETF PATH (TEST A)) + #S(PATHNAME SYSTEM::HOST "sirius" SYSTEM::DEVICE + "disk00$abt43" DIRECTORY "[heicking.comlisp]" SYSTEM::NAME "a" TYPE "raf" + SYSTEM::VERSION 3)) + +#+XCL +(my-assert + (MAPCAR (FUNCTION PATHNAME-HOST) (LIST SYMBOL STRING STREAM PATH)) + (NIL NIL NIL NIL)) + +#+XCL +(my-assert + (MAPCAR (FUNCTION PATHNAME-DEVICE) (LIST SYMBOL STRING STREAM PATH)) + ("DISK00$ABT43" "DISK00$ABT43" "DISK00$ABT43" "DISK00$ABT43")) + +#+XCL +(my-assert + (MAPCAR (FUNCTION PATHNAME-DIRECTORY) (LIST SYMBOL STRING STREAM PATH)) + ("XCL.MAIN" "XCL.MAIN" "XCL.MAIN" "XCL.MAIN")) + +(my-assert + (PROGN (CLOSE STREAM) T) + T) + +#+XCL +(my-assert + (USER-HOMEDIR-PATHNAME) + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE + "DISK00$ABT43" DIRECTORY "HEICKING" SYSTEM::NAME NIL TYPE NIL SYSTEM::VERSION + NIL)) + +(my-assert + (PATHNAME "*.*") + #+XCL + #S(PATHNAME SYSTEM::HOST NIL SYSTEM::DEVICE "DISK00$ABT43" + DIRECTORY "HEICKING" SYSTEM::NAME "*" TYPE :WILD SYSTEM::VERSION NIL) + #+CLISP + #S(PATHNAME :HOST NIL :DEVICE NIL :DIRECTORY (:RELATIVE) + :NAME :WILD :TYPE :WILD :VERSION NIL) + #-(or XCL CLISP) + #P"*.*") + +(my-assert + (progn (setf file (open "nicht-vorhandenes-file.non" + :direction :input + :element-type 'character + :if-does-not-exist :create)) t) + t + "") + +(my-assert + (null (probe-file "nicht-vorhandenes-file.non")) + NIL) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'string-char + :if-exists :error)) + error) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :new-version))) + nil + "") + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :rename))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :rename-and-delete))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :overwrite))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :append))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists :supersede))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-exists nil)) + nil) + +(my-assert + (progn (close file) t) + error) + +(my-assert + (setf file (open "nicht-vorhandenes-file.new" + :direction :io + :element-type 'character + :if-does-not-exist :error)) + error) + +(my-assert + (progn (close file) t) + error) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.new" + :direction :io + :element-type 'character + :if-does-not-exist :create))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (null (setf file (open "nicht-vorhandenes-file.non" + :direction :io + :element-type 'character + :if-does-not-exist nil))) + nil) + +(my-assert + (progn (close file) t) + t) + +(my-assert + (namestring + (multiple-value-setq (new-name pathname truename) + (rename-file "nicht-vorhandenes-file.non" "file.da"))) + "file.da") + +(my-assert + (namestring new-name) + "file.da") + +(my-assert + (null pathname) + nil) + +(my-assert + (null truename) + nil) + +(my-assert + (progn (delete-file "test-pathname.abc") t) + t) + +(my-assert + (progn (mapc #'delete-file (directory "nicht-vorhandenes-file.*")) t) + t) + +(my-assert + (progn (delete-file "file.da") t) + t) + +(my-assert + (progn + (setf (logical-pathname-translations "clocc") + '(("**;*" "/usr/local/src/clocc/**/*"))) + nil) + nil) + +(my-assert + (translate-logical-pathname "clocc:src;port;") + #P"/usr/local/src/clocc/src/port/") diff --git a/src/ansi-tests/readtable.lisp b/src/ansi-tests/readtable.lisp new file mode 100644 index 000000000..4a33d9e8e --- /dev/null +++ b/src/ansi-tests/readtable.lisp @@ -0,0 +1,651 @@ +;;; based on v1.1.1.1 -*- mode: lisp -*- +(in-package :cl-user) + +;; **************************************************************************** +;; * Rosenmueller tel.340 Testquelle READTABLE.que 23.03.1988 * +;; **************************************************************************** + +(my-assert + (prin1-to-string (setq *readtable* (copy-readtable nil))) + "# +NIL>") + +(my-assert + (setq $ 23) + 23) + +(my-assert + (defun single-dollar-reader (stream char) + (declare (ignore stream)) + (intern (string char))) + SINGLE-DOLLAR-READER) + +(my-assert + (set-macro-character #\$ #'single-dollar-reader) + T) + +(my-assert + $ + 23) + +(my-assert + 45 + 45 + ;; => 23 => 45 + (prin1-to-string (get-macro-character #\$)) + "#") + + +(my-assert + (progn (setq *readtable* (copy-readtable nil)) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" ) + 117) + +(my-assert + (sys::rt-bitmask-char #\( ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ ) + 2306) + +(my-assert + (sys::rt-bitmask-char #\x ) + 4097) + +(my-assert + (sys::rt-bitmask-char #\y ) + 1) + +(my-assert + (set-syntax-from-char #\" #\( ) + T) + +(my-assert + (sys::rt-bitmask-char #\" ) + 917) + +(my-assert + (sys::rt-bitmask-char #\( ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ ) + 2306 + ;; *readtable* nil + ;; *readtable* cl-standard + (progn (setq doppelquote-liston-readtable (copy-readtable)) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" doppelquote-liston-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\( doppelquote-liston-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) doppelquote-liston-readtable ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ doppelquote-liston-readtable ) + 2306) + +(my-assert + '"1 2 3) +(1 2 3)) + +(my-assert + (set-syntax-from-char #\" #\\ ) +T) + +(my-assert + (sys::rt-bitmask-char #\" ) +2306) + +(my-assert + (sys::rt-bitmask-char #\( ) +917) + +(my-assert + (sys::rt-bitmask-char #\) ) +165) + +(my-assert + (sys::rt-bitmask-char #\\ ) +2306) + +(my-assert + (progn (setq doppelquote-backslash-readtable (copy-readtable)) t) +T) + +(my-assert + (sys::rt-bitmask-char #\" doppelquote-backslash-readtable ) +2306) + +(my-assert + (sys::rt-bitmask-char #\\ doppelquote-backslash-readtable ) +2306) + +(my-assert + (sys::rt-bitmask-char #\( doppelquote-backslash-readtable ) +917) + +(my-assert + (sys::rt-bitmask-char #\) doppelquote-backslash-readtable ) +165) + +(my-assert + #"< + #\<) + +(my-assert + (progn (setq 2.-doppelquote-backslash-readtable + (copy-readtable doppelquote-backslash-readtable)) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" 2.-doppelquote-backslash-readtable ) + 2306) + +(my-assert + (sys::rt-bitmask-char #\\ 2.-doppelquote-backslash-readtable ) + 2306) + +(my-assert + (sys::rt-bitmask-char #\( 2.-doppelquote-backslash-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) 2.-doppelquote-backslash-readtable ) + 165) + +(my-assert + (progn (setq 2.-doppelquote-liston-readtable + (copy-readtable doppelquote-liston-readtable)) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" 2.-doppelquote-liston-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\( 2.-doppelquote-liston-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) 2.-doppelquote-liston-readtable ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ 2.-doppelquote-liston-readtable ) + 2306) + +(my-assert + (progn (setq cl-standard-readtable + (copy-readtable nil)) + (setq *readtable* cl-standard-readtable) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" cl-standard-readtable ) + 117) + +(my-assert + (sys::rt-bitmask-char #\( cl-standard-readtable ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) cl-standard-readtable ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ cl-standard-readtable ) + 2306) + +(my-assert + (sys::rt-bitmask-char #\" ) + 117) + +(my-assert + (sys::rt-bitmask-char #\( ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ ) + 2306) + +(my-assert + "1234" + "1234") + +(my-assert + (progn (setq *readtable* 2.-doppelquote-liston-readtable) t) + t) + +(my-assert + (sys::rt-bitmask-char #\" ) + 917) + +(my-assert + (sys::rt-bitmask-char #\( ) + 917) + +(my-assert + (sys::rt-bitmask-char #\) ) + 165) + +(my-assert + (sys::rt-bitmask-char #\\ ) + 2306) + +(my-assert + '"1 2 3) +(1 2 3) + +(progn (setq *readtable* doppelquote-backslash-readtable) t) +T + +(sys::rt-bitmask-char #\" ) +2306 + +(sys::rt-bitmask-char #\( ) +917 + +(sys::rt-bitmask-char #\) ) +165 + +(sys::rt-bitmask-char #\\ ) +2306 + +#"< + #\<) + +(my-assert + (readtablep 2.-doppelquote-backslash-readtable ) + T) + +(readtablep 1) +NIL + + +(set-syntax-from-char #\" #\" 2.-doppelquote-backslash-readtable ) +T + +(sys::rt-bitmask-char #\" 2.-doppelquote-backslash-readtable ) +117 + +(sys::rt-bitmask-char #\\ 2.-doppelquote-backslash-readtable ) +2306 + +(sys::rt-bitmask-char #\( 2.-doppelquote-backslash-readtable ) +917 + +(sys::rt-bitmask-char #\) 2.-doppelquote-backslash-readtable ) +165 + + +(set-syntax-from-char #\) #\( 2.-doppelquote-backslash-readtable ) +T + +(sys::rt-bitmask-char #\" 2.-doppelquote-backslash-readtable ) +117 + +(sys::rt-bitmask-char #\\ 2.-doppelquote-backslash-readtable ) +2306 + +(sys::rt-bitmask-char #\( 2.-doppelquote-backslash-readtable ) +917 + +(sys::rt-bitmask-char #\) 2.-doppelquote-backslash-readtable ) +917 + + +(set-syntax-from-char #\( #\) 2.-doppelquote-backslash-readtable ) +T + +(sys::rt-bitmask-char #\" 2.-doppelquote-backslash-readtable ) +117 + +(sys::rt-bitmask-char #\\ 2.-doppelquote-backslash-readtable ) +2306 + +(sys::rt-bitmask-char #\( 2.-doppelquote-backslash-readtable ) +165 + +(sys::rt-bitmask-char #\) 2.-doppelquote-backslash-readtable ) +917 + + +(set-syntax-from-char #\( #\( 2.-doppelquote-liston-readtable + 2.-doppelquote-backslash-readtable ) +T + +(sys::rt-bitmask-char #\" 2.-doppelquote-liston-readtable ) +917 + +(sys::rt-bitmask-char #\( 2.-doppelquote-liston-readtable ) +165 + +(sys::rt-bitmask-char #\) 2.-doppelquote-liston-readtable ) +165 + +(sys::rt-bitmask-char #\\ 2.-doppelquote-liston-readtable ) +2306 + + +(set-syntax-from-char #\) #\) 2.-doppelquote-liston-readtable + 2.-doppelquote-backslash-readtable ) +T + +(sys::rt-bitmask-char #\" 2.-doppelquote-liston-readtable ) +917 + +(sys::rt-bitmask-char #\( 2.-doppelquote-liston-readtable ) +165 + +(sys::rt-bitmask-char #\) 2.-doppelquote-liston-readtable ) +917 + +(sys::rt-bitmask-char #\\ 2.-doppelquote-liston-readtable ) +2306 + + +(progn (setq *readtable* 2.-doppelquote-backslash-readtable ) t) +t + +)sys::rt-bitmask-char #\( ( +165 + +)sys::rt-bitmask-char #\) ( +917 + +)sys::rt-bitmask-char #\\ ( +2306 + +"1234" +"1234" + +')1 2 3( +(1 2 3) + +)progn )setq *readtable* 2.-doppelquote-liston-readtable ( t( +t + + +)sys::rt-bitmask-char #\( ( +165 + +)sys::rt-bitmask-char #\) ( +917 + +)sys::rt-bitmask-char #\\ ( +2306 + +'"1234( +(1234) + +')1 2 3( +(1 2 3) +;; ) muesste listen-anfang-sein +)progn )setq *readtable* )copy-readtable nil(( t( +t + +(sys::rt-bitmask-char #\" ) +117 + +(sys::rt-bitmask-char #\( ) +917 + +(sys::rt-bitmask-char #\) ) +165 + +(sys::rt-bitmask-char #\\ ) +2306 + +(sys::rt-bitmask-char #\x ) +4097 + +(sys::rt-bitmask-char #\y ) +1 + + +(make-dispatch-macro-character #\x) +T + +(sys::rt-bitmask-char #\x ) +4109 + +(sys::rt-bitmask-char #\y ) +1 + +(defun d1 (a b c) (princ "1.dmacro")) +D1 + +(d1 1 2 3) +"1.dmacro" + +(set-dispatch-macro-character #\x #\. #'d1) +T + +(sys::rt-bitmask-char #\x ) +4109 + +(prin1-to-string (get-dispatch-macro-character #\x #\.)) +"#" + +(multiple-value-list (read-from-string "123x.45")) +( 123 3) + +(multiple-value-list (read-from-string "123x.45" t nil :start 3)) +( "1.dmacro" 5) + +(multiple-value-list (read-from-string "123x.45" t nil :start 5)) +(45 7) + + +(make-dispatch-macro-character #\y) +T + +(s\Ys::rt-bitmask-char #\x ) +4109 + +(s\Ys::rt-bitmask-char #\y ) +13 + +(defun d2 (a b c) (princ "2.dmacro")) +D2 + +(d2 1 2 3) +"2.dmacro" + +(set-dispatch-macro-character #\y #\, #'d2) +T + +(s\Ys::rt-bitmask-char #\x ) +4109 + +(s\Ys::rt-bitmask-char #\y ) +13 + +(prin1-to-string (get-dispatch-macro-character #\x #\.)) +"#" + +(prin1-to-string (get-dispatch-macro-character #\y #\,)) +"#" + +(multiple-value-list (read-from-string "123y,45")) +( 123 3) + +(multiple-value-list (read-from-string "123y,45" t nil :start 3)) +( "2.dmacro" 5) + +(multiple-value-list (read-from-string "123y,45" t nil :start 5)) +(45 7) + +(set-dispatch-macro-character #\x #\. #'d2) +T + +(s\Ys::rt-bitmask-char #\x ) +4109 + +(s\Ys::rt-bitmask-char #\y ) +13 + +(prin1-to-string (get-dispatch-macro-character #\y #\,)) +"#" + +(prin1-to-string (get-dispatch-macro-character #\x #\.)) +"#" + +(multiple-value-list (read-from-string "123x.45")) +( 123 3) + +(multiple-value-list (read-from-string "123x.45" t nil :start 3)) +( "2.dmacro" 5) + +(multiple-value-list (read-from-string "123x.45" t nil :start 5)) +(45 7) + +(set-dispatch-macro-character #\y #\. #'d1) +T + +(s\Ys::rt-bitmask-char #\x ) +4109 + +(s\Ys::rt-bitmask-char #\y ) +13 + +(prin1-to-string (get-dispatch-macro-character #\x #\.)) +"#" + +(prin1-to-string (get-dispatch-macro-character #\y #\,)) +"#" + +(prin1-to-string (get-dispatch-macro-character #\y #\.)) +"#" + +(multiple-value-list (read-from-string "123y.45")) +( 123 3) + +(multiple-value-list (read-from-string "123y.45" t nil :start 3)) +( "1.dmacro" 5) + +(multiple-value-list (read-from-string "123y.45" t nil :start 5)) +(45 7) + +(multiple-value-list (read-from-string "123y,45")) +( 123 3) + +(multiple-value-list (read-from-string "123y,45" t nil :start 3)) +( "2.dmacro" 5) + +(multiple-value-list (read-from-string "123y,45" t nil :start 5)) +(45 7) + +(progn (setq *readtable* (cop\Y-readtable nil nil)) t) +t + +(sys::rt-bitmask-char #\x ) +4097 + +(sys::rt-bitmask-char #\y ) +1 + +(get-dispatch-macro-character #\x #\.) +ERROR + +(get-dispatch-macro-character #\y #\,) +ERROR + +(get-dispatch-macro-character #\y #\.) +ERROR + +(defun |#{-reader| (stream char arg) + (declare (ignore char arg)) + (mapcon #'(lambda (x) + (mapcar #'(lambda (y)(list (car x) y))(cdr x))) + (read-delimited-list #\} stream))) +|#{|-|reader| + +(set-dispatch-macro-character #\# #\{ #'|#{-reader|) +T + +;; (set-macro-character #\} (get-macro-character #\)) nil)) +;; geht bei uns nicht ! +;; dafuer : +(set-syntax-from-char #\} #\) ) +;; nicht notwendig, da superklammer +(progn +(setq read-st (make-string-input-stream "#{p q z a} #{a b c d}")) t) +T + +(read read-st) +((P Q) (P Z) (P A) (Q Z) (Q A) (Z A)) + +(read read-st) +((A B) (A C) (A D) (B C) (B D) (C D)) + +(progn (setq *readtable* (copy-readtable nil nil)) + (makunbound 'doppelquote-liston-readtable) + (makunbound 'doppelquote-backslash-readtable) + (makunbound '2.-doppelquote-liston-readtable) + (makunbound '2.-doppelquote-backslash-readtable) + (makunbound 'cl-standard-readtable) + (makunbound 'read-st) + (makunbound '$) +t) +T + diff --git a/src/ansi-tests/section10.lisp b/src/ansi-tests/section10.lisp new file mode 100644 index 000000000..1d33dc314 --- /dev/null +++ b/src/ansi-tests/section10.lisp @@ -0,0 +1,960 @@ +;;; section 10: symbols -*- mode: lisp -*- +(in-package :cl-user) + +;;; symbolp + +(my-assert + (symbolp 'elephant) + t) + + +(my-assert + (symbolp 12) + nil) + + +(my-assert + (symbolp nil) + t) + + +(my-assert + (symbolp '()) + t) + + +(my-assert + (symbolp :test) + t) + + +(my-assert + (symbolp "hello") + nil) + +;;; keywordp + +(my-assert + (keywordp 'elephant) + nil) + + +(my-assert + (keywordp 12) + nil) + + +(my-assert + (keywordp :test) + t) + + +(my-assert + (keywordp ':test) + t) + + +(my-assert + (keywordp nil) + nil) + + +(my-assert + (keywordp :nil) + t) + + +(my-assert + (keywordp '(:test)) + nil) + + +(my-assert + (keywordp "hello") + nil) + + +(my-assert + (keywordp ":hello") + nil) + + +(my-assert + (keywordp '&optional) + nil) + +;;; make-symbol + + +(my-assert + (setq temp-string "temp") + "temp") + + +(my-assert + (progn + (setq temp-symbol (make-symbol temp-string)) + t) + t) + + +(my-assert + (symbol-name temp-symbol) + "temp") + + +(my-assert + (eq (symbol-name temp-symbol) temp-string) + #+(or cmu sbcl clisp ecls) t + #-(or cmu sbcl clisp ecls) fill-this-in) + + +(my-assert + (multiple-value-bind (a b) + (find-symbol "temp") + (list a b)) + ( NIL NIL)) + + +(my-assert + (eq (make-symbol temp-string) (make-symbol temp-string)) + nil) + +;;; copy-symbol + + +(my-assert + (setq fred 'fred-smith) + FRED-SMITH) + + +(my-assert + (setf (symbol-value fred) 3) + 3) + + +(my-assert + (progn + (setq fred-clone-1a (copy-symbol fred nil)) + t) + t) + + +(my-assert + (progn + (setq fred-clone-1b (copy-symbol fred nil)) + t) + t) + + +(my-assert + (progn + (setq fred-clone-2a (copy-symbol fred t)) + t) + t) + + +(my-assert + (progn + (setq fred-clone-2b (copy-symbol fred t)) + t) + t) + + +(my-assert + (eq fred fred-clone-1a) + nil) + + +(my-assert + (eq fred-clone-1a fred-clone-1b) + nil) + + +(my-assert + (eq fred-clone-2a fred-clone-2b) + nil) + + +(my-assert + (eq fred-clone-1a fred-clone-2a) + nil) + + +(my-assert + (symbol-value fred) + 3) + + +(my-assert + (boundp fred-clone-1a) + nil) + + +(my-assert + (symbol-value fred-clone-2a) + 3) + + +(my-assert + (setf (symbol-value fred-clone-2a) 4) + 4) + + +(my-assert + (symbol-value fred) + 3) + + +(my-assert + (symbol-value fred-clone-2a) + 4) + + +(my-assert + (symbol-value fred-clone-2b) + 3) + + +(my-assert + (boundp fred-clone-1a) + nil) + + +(my-assert + (progn + (setf (symbol-function fred) #'(lambda (x) x)) + t) + t) + + +(my-assert + (fboundp fred) + t) + + +(my-assert + (fboundp fred-clone-1a) + nil) + + +(my-assert + (fboundp fred-clone-2a) + nil) + +;;; symbol-function + + +(my-assert + (progn + (symbol-function 'car) + t) + t) + +(my-assert + (symbol-function 'twice) + UNDEFINED-FUNCTION) + + +(my-assert + (defun twice (n) (* n 2)) + TWICE) + + +(my-assert + (progn + (symbol-function 'twice) + t) + t) + + +(my-assert + (list (twice 3) + (funcall (function twice) 3) + (funcall (symbol-function 'twice) 3)) + (6 6 6)) + + +(my-assert + (flet ((twice (x) (list x x))) + (list (twice 3) + (funcall (function twice) 3) + (funcall (symbol-function 'twice) 3))) + ((3 3) (3 3) 6) ) + + +(my-assert + (progn + (setf (symbol-function 'twice) #'(lambda (x) (list x x))) + t) + t) + + +(my-assert + (list (twice 3) + (funcall (function twice) 3) + (funcall (symbol-function 'twice) 3)) + ((3 3) (3 3) (3 3))) + + +(my-assert + (fboundp 'defun) + t) + + +(my-assert + (progn + (symbol-function 'defun) + t) + t) + + +(my-assert + (progn + (functionp (symbol-function 'defun)) + t) + t) + + +(my-assert + (defun symbol-function-or-nil (symbol) + (if (and (fboundp symbol) + (not (macro-function symbol)) + (not (special-operator-p symbol))) + (symbol-function symbol) + nil)) + SYMBOL-FUNCTION-OR-NIL) + + +(my-assert + (progn + (symbol-function-or-nil 'car) + t) + t) + + +(my-assert + (symbol-function-or-nil 'defun) + NIL) + +;;; symbol-name + + +(my-assert + (symbol-name 'temp) + "TEMP" ) + + +(my-assert + (symbol-name :start) + "START") + +;;; symbol-package + + +(my-assert + (progn + (in-package "CL-USER") + t) + t) + + + +(my-assert + (progn + (symbol-package 'car) + t) + t) + + + +(my-assert + (progn + (symbol-package 'bus) + t) + t) + + +(my-assert + (progn + (symbol-package :optional) + t) + t) + + +;; Gensyms are uninterned, so have no home package. + +(my-assert + (symbol-package (gensym)) + NIL) + + +(if (find-package "PK2") + (delete-package + (find-package "PK2"))) + +(if (find-package "PK1") + (delete-package + (find-package "PK1"))) + +(my-assert + (find-package "PK1") + nil) + +(my-assert + (progn + (make-package 'pk1) + t) + t) + + +(my-assert + (multiple-value-bind (a b) + (intern "SAMPLE1" "PK1") + (list a b)) + (PK1::SAMPLE1 :internal)) + + +(my-assert + (export (find-symbol "SAMPLE1" "PK1") "PK1") + T) + + +(my-assert + (progn + (make-package 'pk2 :use '(pk1)) + t) + t) + + +(my-assert + (multiple-value-bind (a b) + (find-symbol "SAMPLE1" "PK2") + (list a b)) + (PK1:SAMPLE1 :INHERITED)) + + +(my-assert + (progn + (symbol-package 'pk1::sample1) + t) + t) + + +(my-assert + (progn + (symbol-package 'pk2::sample1) + t) + t) + + +(my-assert + (progn + (symbol-package 'pk1::sample2) + t) + t) + + +(my-assert + (progn + (symbol-package 'pk2::sample2) + t) + t) + +;; The next several forms create a scenario in which a symbol +;; is not really uninterned, but is "apparently uninterned", +;; and so SYMBOL-PACKAGE still returns NIL. + +(my-assert + (setq s3 'pk1::sample3) + PK1::SAMPLE3) + + +(my-assert + (import s3 'pk2) + T) + + +(my-assert + (unintern s3 'pk1) + T) + + +(my-assert + (symbol-package s3) + NIL) + + +(my-assert + (eq s3 'pk2::sample3) + T) + +;;; symbol-plist + + +(setq sym (gensym)) + +(my-assert + (symbol-plist sym) + ()) + + +(my-assert + (setf (get sym 'prop1) 'val1) + VAL1) + + +(my-assert + (symbol-plist sym) + (PROP1 VAL1)) + + +(my-assert + (setf (get sym 'prop2) 'val2) + VAL2) + + +(my-assert + (symbol-plist sym) + (PROP2 VAL2 PROP1 VAL1)) + + +(my-assert + (setf (symbol-plist sym) (list 'prop3 'val3)) + (PROP3 VAL3)) + + +(my-assert + (symbol-plist sym) + (PROP3 VAL3)) + +;;; setf + + +(my-assert + (setf (symbol-value 'a) 1) + 1) + + +(my-assert + (symbol-value 'a) + 1) + +;; SYMBOL-VALUE can see dynamic variables. + +(my-assert + (let ((a 2)) + (declare (special a)) + (symbol-value 'a)) + 2) + + +(my-assert + (let ((a 2)) + (declare (special a)) + (setq a 3) + (symbol-value 'a)) + 3) + + +(my-assert + (let ((a 2)) + (setf (symbol-value 'a) 3) + t) + t) + + + ;(my-assert + ;a + ;3) + + + ;(my-assert + ;(symbol-value 'a) + ;3) + + +(my-assert + (multiple-value-bind (h j) + (let ((a 4)) + (declare (special a)) + (let ((b (symbol-value 'a))) + (setf (symbol-value 'a) 5) + (values a b))) + (list h j)) + (5 4)) + + + ;(my-assert + ;a + ;3) + + +(my-assert + (symbol-value :any-keyword) + :ANY-KEYWORD) + + +(my-assert + (symbol-value 'nil) + NIL) + + +(my-assert + (symbol-value '()) + NIL) + +;; The precision of this next one is implementation-dependent. + +(my-assert + (symbol-value 'pi) + #-clisp + 3.141592653589793d0 + #+clisp + 3.1415926535897932385L0) + +;;; get + + +(my-assert + (defun make-person (first-name last-name) + (let ((person (gensym "PERSON"))) + (setf (get person 'first-name) first-name) + (setf (get person 'last-name) last-name) + person)) + MAKE-PERSON) + + +(my-assert + (defvar *john* (make-person "John" "Dow")) + *JOHN*) + + +(my-assert + (progn + *john* + t) + t) + + +(my-assert + (defvar *sally* (make-person "Sally" "Jones")) + *SALLY*) + + +(my-assert + (get *john* 'first-name) + "John") + + +(my-assert + (get *sally* 'last-name) + "Jones") + + +(my-assert + (defun marry (man woman married-name) + (setf (get man 'wife) woman) + (setf (get woman 'husband) man) + (setf (get man 'last-name) married-name) + (setf (get woman 'last-name) married-name) + married-name) + MARRY) + + +(my-assert + (marry *john* *sally* "Dow-Jones") + "Dow-Jones") + + +(my-assert + (get *john* 'last-name) + "Dow-Jones") + + +(my-assert + (get (get *john* 'wife) 'first-name) + "Sally") + + +(my-assert + (progn + (symbol-plist *john*) + t) + t) + + +(my-assert + (defmacro age (person &optional (default ''thirty-something)) + `(get ,person 'age ,default)) + AGE) + + +(my-assert + (age *john*) + THIRTY-SOMETHING) + + +(my-assert + (age *john* 20) + 20) + + +(my-assert + (setf (age *john*) 25) + 25) + + +(my-assert + (age *john*) + 25) + + +(my-assert + (age *john* 20) + 25) + +;;; remprop + + +(my-assert + (progn + (setq test (make-symbol "PSEUDO-PI")) + t) + t) + + +(my-assert + (symbol-plist test) + ()) + + +(my-assert + (setf (get test 'constant) t) + T) + + +(my-assert + (setf (get test 'approximation) 3.14) + 3.14) + + +(my-assert + (setf (get test 'error-range) 'noticeable) + NOTICEABLE) + + +(my-assert + (symbol-plist test) + (ERROR-RANGE NOTICEABLE APPROXIMATION 3.14 CONSTANT T)) + + +(my-assert + (setf (get test 'approximation) nil) + NIL) + + +(my-assert + (symbol-plist test) + (ERROR-RANGE NOTICEABLE APPROXIMATION NIL CONSTANT T)) + + +(my-assert + (get test 'approximation) + NIL) + + +(my-assert + (not (remprop test 'approximation)) + nil) + + +(my-assert + (get test 'approximation) + NIL) + + +(my-assert + (symbol-plist test) + (ERROR-RANGE NOTICEABLE CONSTANT T)) + + +(my-assert + (remprop test 'approximation) + NIL) + + +(my-assert + (symbol-plist test) + (ERROR-RANGE NOTICEABLE CONSTANT T)) + + +(my-assert + (not (remprop test 'error-range)) + nil) + + +(my-assert + (setf (get test 'approximation) 3) + 3) + + +(my-assert + (symbol-plist test) + (APPROXIMATION 3 CONSTANT T)) + + +;;; boundp + + +(my-assert + (setq x 1) + 1) + + +(my-assert + (boundp 'x) + t) + + +(my-assert + (makunbound 'x) + X) + + +(my-assert + (boundp 'x) + nil) + + + +(my-assert + (let ((x 2)) (declare (special x)) (boundp 'x)) + t) + +;;; mkunbound + + +(my-assert + (setf (symbol-value 'a) 1) + 1) + + +(my-assert + (boundp 'a) + t) + + +(my-assert + a + 1) + + +(my-assert + (makunbound 'a) + A) + + +(my-assert + (boundp 'a) + nil) + +;;; set + + +(my-assert + (setf (symbol-value 'n) 1) + 1) + + +(my-assert + (set 'n 2) + 2) + + +(my-assert + (symbol-value 'n) + 2) + + + ;(my-assert + ;(let ((n 3)) + ; (declare (special n)) + ; (setq n (+ n 1)) + ; (setf (symbol-value 'n) (* n 10)) + ; (set 'n (+ (symbol-value 'n) n)) + ; n) + ;80) + + + ;(my-assert + ;n + ;2) + + + ;(my-assert + ;(let ((n 3)) + ; (setq n (+ n 1)) + ; (setf (symbol-value 'n) (* n 10)) + ; (set 'n (+ (symbol-value 'n) n)) + ; n) + ;4) + + + ;(my-assert + ;n + ;44) + + +(my-assert + (defvar *n* 2) + *N*) + + +(my-assert + (let ((*n* 3)) + (setq *n* (+ *n* 1)) + (setf (symbol-value '*n*) (* *n* 10)) + (set '*n* (+ (symbol-value '*n*) *n*)) + *n*) + 80) + + +(my-assert + *n* + 2) + + +(my-assert + (defvar *even-count* 0) + *EVEN-COUNT*) + + +(my-assert + (defvar *odd-count* 0) + *ODD-COUNT*) + + +(my-assert + (defun tally-list (list) + (dolist (element list) + (set (if (evenp element) '*even-count* '*odd-count*) + (+ element (if (evenp element) *even-count* *odd-count*))))) + tally-list) + + +(my-assert + (tally-list '(1 9 4 3 2 7)) + NIL) + + +(my-assert + *even-count* + 6) + + + +(my-assert + *odd-count* + 20) + diff --git a/src/ansi-tests/section11.lisp b/src/ansi-tests/section11.lisp new file mode 100644 index 000000000..0afe742ed --- /dev/null +++ b/src/ansi-tests/section11.lisp @@ -0,0 +1,5 @@ +;;; section 11: packages -*- mode: lisp -*- +(in-package :cl-user) + + +;;; bah diff --git a/src/ansi-tests/section12.lisp b/src/ansi-tests/section12.lisp new file mode 100644 index 000000000..b7133d462 --- /dev/null +++ b/src/ansi-tests/section12.lisp @@ -0,0 +1,861 @@ +;;; 12: numbers -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; 12.1.4.1.1 + +;;;; Combining rationals with floats. +;;; This example assumes an implementation in which +;;; (float-radix 0.5) is 2 (as in IEEE) or 16 (as in IBM/360), +;;; or else some other implementation in which 1/2 has an exact +;;; representation in floating point. +(my-assert + (+ 1/2 0.5) + 1.0) + + +(my-assert + (- 1/2 0.5d0) + 0.0d0) + + +(my-assert + (+ 0.5 -0.5 1/2) + 0.5) + +;;;; Comparing rationals with floats. +;;; This example assumes an implementation in which the default float +;;; format is IEEE single-float, IEEE double-float, or some other format +;;; in which 5/7 is rounded upwards by FLOAT. + +(my-assert + (< 5/7 (float 5/7)) + t) + + +(my-assert + (< 5/7 (rational (float 5/7))) + t) + + +(my-assert + (< (float 5/7) (float 5/7)) + nil) + +;;; 12.1.5.3.1 + + +(my-assert + #c(1.0 1.0) + #C(1.0 1.0)) + +(my-assert + #c(0.0 0.0) + #C(0.0 0.0)) + +(my-assert + #c(1.0 1) + #C(1.0 1.0)) + +(my-assert + #c(0.0 0) + #C(0.0 0.0)) + +(my-assert + #c(1 1) + #C(1 1)) + +(my-assert + #c(0 0) + 0) + +(my-assert + (typep #c(1 1) '(complex (eql 1))) + t) + + +(my-assert + (typep #c(0 0) '(complex (eql 0))) + nil) + +;;; number + + +(my-assert + (subtypep 'real 'number) + t) + + +(my-assert + (subtypep 'complex 'number) + t) + + +(my-assert + (subtypep 'rational 'real) + t) + + +(my-assert + (subtypep 'float 'real) + t) + + +;;; float + + +(my-assert + (subtypep 'short-float 'float) + t) + + +(my-assert + (subtypep 'single-float 'float) + t) + + +(my-assert + (subtypep 'double-float 'float) + t) + + +(my-assert + (subtypep 'long-float 'float) + t) + +;;; rational + + +(my-assert + (subtypep 'integer 'rational) + t) + + +(my-assert + (subtypep 'ratio 'rational) + t) + +;;; integer + + +(my-assert + (subtypep 'fixnum 'integer) + t) + + +(my-assert + (subtypep 'bignum 'integer) + t) +;;; fixnum + +(my-assert + (subtypep '(signed-byte 16) 'fixnum) + t) +;;; = /= < > <= >= + +(my-assert + (= 3 3) + t) + +(my-assert + (/= 3 3) + nil) + +(my-assert + (= 3 5) + nil) + +(my-assert + (/= 3 5) + t) + +(my-assert + (= 3 3 3 3) + t) + +(my-assert + (/= 3 3 3 3) + nil) + +(my-assert + (= 3 3 5 3) + nil) + +(my-assert + (/= 3 3 5 3) + nil) + +(my-assert + (= 3 6 5 2) + nil) + +(my-assert + (/= 3 6 5 2) + t) + +(my-assert + (= 3 2 3) + nil) + +(my-assert + (/= 3 2 3) + nil) + +(my-assert + (< 3 5) + t) + +(my-assert + (<= 3 5) + t) + +(my-assert + (< 3 -5) + nil) + +(my-assert + (<= 3 -5) + nil) + +(my-assert + (< 3 3) + nil) + +(my-assert + (<= 3 3) + t) + +(my-assert + (< 0 3 4 6 7) + t) + +(my-assert + (<= 0 3 4 6 7) + t) + +(my-assert + (< 0 3 4 4 6) + nil) + +(my-assert + (<= 0 3 4 4 6) + t) + +(my-assert + (> 4 3) + t) + +(my-assert + (>= 4 3) + t) + +(my-assert + (> 4 3 2 1 0) + t) + +(my-assert + (>= 4 3 2 1 0) + t) + +(my-assert + (> 4 3 3 2 0) + nil) + +(my-assert + (>= 4 3 3 2 0) + t) + +(my-assert + (> 4 3 1 2 0) + nil) + +(my-assert + (>= 4 3 1 2 0) + nil) + +(my-assert + (= 3) + t) + +(my-assert + (/= 3) + t) + +(my-assert + (< 3) + t) + +(my-assert + (<= 3) + t) + +(my-assert + (= 3.0 #c(3.0 0.0)) + t) + +(my-assert + (/= 3.0 #c(3.0 1.0)) + t) + +(my-assert + (= 3 3.0) + t) + +(my-assert + (= 3.0s0 3.0d0) + t) + +(my-assert + (= 0.0 -0.0) + t) + +(my-assert + (= 5/2 2.5) + t) +(my-assert + (> 0.0 -0.0) + nil) +(my-assert + (= 0 -0.0) + t) + + +;;; min max + + +(my-assert + (max 3) + 3 ) + + +(my-assert + (min 3) + 3) + + +(my-assert + (max 6 12) + 12 ) + + +(my-assert + (min 6 12) + 6) + + +(my-assert + (max -6 -12) + -6 ) + + +(my-assert + (min -6 -12) + -12) + + +(my-assert + (max 1 3 2 -7) + 3 ) + + +(my-assert + (min 1 3 2 -7) + -7) + + +(my-assert + (max -2 3 0 7) + 7 ) + + +(my-assert + (min -2 3 0 7) + -2) + + +(my-assert + (max 5.0 2) + 5.0 ) + + +(my-assert + (min 5.0 2) + #+(or cmu sbcl clisp ecls) 2 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 2 OR 2.0 + + +(my-assert + (max 3.0 7 1) + #+(or cmu sbcl clisp ecls) 7 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 7 OR 7.0 + + +(my-assert + (min 3.0 7 1) + #+(or cmu sbcl clisp ecls) 1 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 1 OR 1.0 + + +(my-assert + (max 1.0s0 7.0d0) + 7.0d0) + + +(my-assert + (min 1.0s0 7.0d0) + #+(or cmu sbcl ecls) 1.0 ;hmm in fact an error? + #+clisp 1.0s0 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 1.0s0 OR 1.0d0 + + +(my-assert + (max 3 1 1.0s0 1.0d0) + #+(or cmu sbcl clisp ecls) 3 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 3 OR 3.0d0 + + +(my-assert + (min 3 1 1.0s0 1.0d0) + #+(or cmu sbcl clisp ecls) 1 + #-(or cmu sbcl clisp ecls) fill-this-in) + ; 1 OR 1.0s0 OR 1.0d0 + +;;; plusp minusp + + +(my-assert + (minusp -1) + t) + + +(my-assert + (plusp 0) + nil) + + +(my-assert + (plusp least-positive-single-float) + t) + + +(my-assert + (plusp least-positive-double-float) + t) + + +(my-assert + (minusp least-positive-single-float) + nil) + + +(my-assert + (minusp least-positive-double-float) + nil) + + +(my-assert + (plusp least-negative-single-float) + nil) + + +(my-assert + (plusp least-negative-double-float) + nil) + + +(my-assert + (minusp least-negative-single-float) + t) + + +(my-assert + (minusp least-negative-double-float) + t) + + +(my-assert + (minusp 0) + nil) + + +(my-assert + (minusp -0.0) + nil) + + +(my-assert + (minusp +0.0) + nil) + + +(my-assert + (plusp 0) + nil) + + +(my-assert + (plusp -0.0) + nil) + + +(my-assert + (plusp +0.0) + nil) + + +;;; zerop + + +(my-assert + (zerop 0) + t) + + +(my-assert + (zerop 0.0) + t) + + +(my-assert + (zerop +0.0) + t) + + +(my-assert + (zerop -0.0) + t) + + +(my-assert + (zerop -1) + nil) + + +(my-assert + (zerop 1) + nil) + + +(my-assert + (zerop 0/100) + t) + + +(my-assert + (zerop #c(0 0.0)) + t) + +;;; random-state-p + + +(my-assert + (random-state-p *random-state*) + t) + + +(my-assert + (random-state-p (make-random-state)) + t) + + +(my-assert + (random-state-p 'test-function) + nil) + +;;; number-p + + +(my-assert + (numberp 12) + t) + + +(my-assert + (numberp (expt 2 130)) + t) + + +(my-assert + (numberp #c(5/3 7.2)) + t) + + +(my-assert + (numberp nil) + nil) + + +(my-assert + (numberp (cons 1 2)) + nil) + +;;; most-positive-fixnum + + + +(my-assert + (>= most-positive-fixnum (- (expt 2 15) 1)) + t) + + +(my-assert + (>= most-positive-fixnum array-dimension-limit) + t + " +most-positive-fixnum is that fixnum closest in value +to positive infinity provided by the implementation, and +greater than or equal to both 2^15 - 1 and array-dimension-limit. +") + + +(my-assert + (<= most-negative-fixnum (- (expt 2 15))) + t) + +;;; most-positive bla bla + + +(my-assert + (plusp MOST-POSITIVE-SHORT-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-SHORT-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-NORMALIZED-SHORT-FLOAT) + t) + + +(my-assert + (plusp MOST-POSITIVE-DOUBLE-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-DOUBLE-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-NORMALIZED-DOUBLE-FLOAT) + t) + + +(my-assert + (plusp MOST-POSITIVE-LONG-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-LONG-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-NORMALIZED-LONG-FLOAT) + t) + + +(my-assert + (plusp MOST-POSITIVE-SINGLE-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-SINGLE-FLOAT) + t) + + +(my-assert + (plusp LEAST-POSITIVE-NORMALIZED-SINGLE-FLOAT) + t) + + +(my-assert + (minusp MOST-NEGATIVE-SHORT-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-SHORT-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-NORMALIZED-SHORT-FLOAT) + t) + + +(my-assert + (minusp MOST-NEGATIVE-SINGLE-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-SINGLE-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-NORMALIZED-SINGLE-FLOAT) + t) + + +(my-assert + (minusp MOST-NEGATIVE-DOUBLE-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-DOUBLE-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-NORMALIZED-DOUBLE-FLOAT) + t) + + +(my-assert + (minusp MOST-NEGATIVE-LONG-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-LONG-FLOAT) + t) + + +(my-assert + (minusp LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT) + t) + +;;; epsilons + + + +(my-assert + (not (= (float 1 short-float-epsilon) + (+ (float 1 short-float-epsilon) short-float-epsilon))) + t + "The value of each of the constants short-float-epsilon, +single-float-epsilon, double-float-epsilon, and +long-float-epsilon is the smallest positive float + of the given format, such that the following +expression is true when evaluated: + +(not (= (float 1 ) (+ (float 1 ) )) + ") + + +(my-assert + (not (= (float 1 single-float-epsilon) + (+ (float 1 single-float-epsilon) single-float-epsilon))) + t + "The value of each of the constants short-float-epsilon, +single-float-epsilon, double-float-epsilon, and +long-float-epsilon is the smallest positive float + of the given format, such that the following +expression is true when evaluated: + +(not (= (float 1 ) (+ (float 1 ) )) + ") + + +(my-assert + (not (= (float 1 double-float-epsilon) + (+ (float 1 double-float-epsilon) double-float-epsilon))) + t + "The value of each of the constants short-float-epsilon, +single-float-epsilon, double-float-epsilon, and +long-float-epsilon is the smallest positive float + of the given format, such that the following +expression is true when evaluated: + +(not (= (float 1 ) (+ (float 1 ) )) + ") + + +(my-assert + (not (= (float 1 long-float-epsilon ) + (+ (float 1 long-float-epsilon ) long-float-epsilon ))) + t + "The value of each of the constants short-float-epsilon, +single-float-epsilon, double-float-epsilon, and +long-float-epsilon is the smallest positive float + of the given format, such that the following +expression is true when evaluated: + +(not (= (float 1 ) (+ (float 1 ) )) + ") + + +(my-assert + (not (= (float 1 short-float-negative-epsilon) + (- (float 1 short-float-negative-epsilon) + short-float-negative-epsilon))) + t + "The value of each of the constants short-float-negative-epsilon, +single-float-negative-epsilon, +double-float-negative-epsilon, and long-float-negative-epsilon +is the smallest positive float of +the given format, such that the following expression +is true when evaluated: + +(not (= (float 1 ) (- (float 1 ) ))) ") + + +(my-assert + (not (= (float 1 single-float-negative-epsilon) + (- (float 1 single-float-negative-epsilon) + single-float-negative-epsilon))) + t + "The value of each of the constants short-float-negative-epsilon, +single-float-negative-epsilon, +double-float-negative-epsilon, and long-float-negative-epsilon +is the smallest positive float of +the given format, such that the following expression +is true when evaluated: + +(not (= (float 1 ) (- (float 1 ) ))) ") + + +(my-assert + (not (= (float 1 double-float-negative-epsilon) + (- (float 1 double-float-negative-epsilon) + double-float-negative-epsilon))) + t + "The value of each of the constants short-float-negative-epsilon, +single-float-negative-epsilon, +double-float-negative-epsilon, and long-float-negative-epsilon +is the smallest positive float of +the given format, such that the following expression +is true when evaluated: + +(not (= (float 1 ) (- (float 1 ) ))) ") + + + +(my-assert + (not (= (float 1 long-float-negative-epsilon) + (- (float 1 long-float-negative-epsilon) + long-float-negative-epsilon))) + t + "The value of each of the constants short-float-negative-epsilon, +single-float-negative-epsilon, +double-float-negative-epsilon, and long-float-negative-epsilon +is the smallest positive float of +the given format, such that the following expression +is true when evaluated: + +(not (= (float 1 ) (- (float 1 ) ))) ") diff --git a/src/ansi-tests/section13.lisp b/src/ansi-tests/section13.lisp new file mode 100644 index 000000000..1ccd24e1a --- /dev/null +++ b/src/ansi-tests/section13.lisp @@ -0,0 +1,583 @@ +;;; 13 characters -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(my-assert + (subtypep 'base-char 'character) + T) + + +(my-assert + (subtypep 'standard-char 'base-char) + t) + + +(my-assert + (subtypep 'extended-char 'character) + t + "Type EXTENDED-CHAR + +Supertypes: + +extended-char, character, t") + +;;; char= etc + + +(my-assert + (char= #\d #\d) + t) + + +(my-assert + (char= #\A #\a) + nil) + + +(my-assert + (char= #\d #\x) + nil) + + +(my-assert + (char= #\d #\D) + nil) + + +(my-assert + (char/= #\d #\d) + nil) + + +(my-assert + (char/= #\d #\x) + t) + + +(my-assert + (char/= #\d #\D) + t) + + +(my-assert + (char= #\d #\d #\d #\d) + t) + + +(my-assert + (char/= #\d #\d #\d #\d) + nil) + + +(my-assert + (char= #\d #\d #\x #\d) + nil) + + +(my-assert + (char/= #\d #\d #\x #\d) + nil) + + +(my-assert + (char= #\d #\y #\x #\c) + nil) + + +(my-assert + (char/= #\d #\y #\x #\c) + t) + + +(my-assert + (char= #\d #\c #\d) + nil) + + +(my-assert + (char/= #\d #\c #\d) + nil) + + +(my-assert + (char< #\d #\x) + t) + + +(my-assert + (char<= #\d #\x) + t) + + +(my-assert + (char< #\d #\d) + nil) + + +(my-assert + (char<= #\d #\d) + t) + + +(my-assert + (char< #\a #\e #\y #\z) + t) + + +(my-assert + (char<= #\a #\e #\y #\z) + t) + + +(my-assert + (char< #\a #\e #\e #\y) + nil) + + +(my-assert + (char<= #\a #\e #\e #\y) + t) + + +(my-assert + (char> #\e #\d) + t) + + +(my-assert + (char>= #\e #\d) + t) + + +(my-assert + (char> #\d #\c #\b #\a) + t) + + +(my-assert + (char>= #\d #\c #\b #\a) + t) + + +(my-assert + (char> #\d #\d #\c #\a) + nil) + + +(my-assert + (char>= #\d #\d #\c #\a) + t) + + +(my-assert + (char> #\e #\d #\b #\c #\a) + nil) + + +(my-assert + (char>= #\e #\d #\b #\c #\a) + nil) + + +(my-assert + (char> #\z #\A) + #+(or cmu sbcl clisp ecls) T + #-(or cmu sbcl clisp ecls) fill-this-in) + + +(my-assert + (char> #\Z #\a) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + + +(my-assert + (char-equal #\A #\a) + t) + + +(my-assert + (stable-sort (list #\b #\A #\B #\a #\c #\C) #'char-lessp) + (#\A #\a #\b #\B #\c #\C)) + + +(my-assert + (stable-sort (list #\b #\A #\B #\a #\c #\C) #'char<) + #+(or cmu sbcl clisp ecls) (#\A #\B #\C #\a #\b #\c) + #-(or cmu sbcl clisp ecls) fill-this-in) + ; (#\A #\B #\C #\a #\b #\c) ;Implementation A + ; (#\a #\b #\c #\A #\B #\C) ;Implementation B + ; (#\a #\A #\b #\B #\c #\C) ;Implementation C + ; (#\A #\a #\B #\b #\C #\c) ;Implementation D + ; (#\A #\B #\a #\b #\C #\c) ;Implementation E + +;;; character + + +(my-assert + (character #\a) + #\a) + + +(my-assert + (character "a") + #\a) + +(my-assert + (character 'a) + #\A) + + +(my-assert + (character '\a) + #\a) + + +(my-assert + (character 65.0) + TYPE-ERROR) + + +(my-assert + (character 'apple) + TYPE-ERROR) + + +;;; alpha-char-p + + +(my-assert + (alpha-char-p #\a) + t) + + +(my-assert + (alpha-char-p #\5) + nil) + + +(my-assert + (alpha-char-p #\Newline) + nil) + +;;; alphanumericp + + +(my-assert + (alphanumericp #\Z) + t) + + +(my-assert + (alphanumericp #\9) + t) + + +(my-assert + (alphanumericp #\Newline) + nil) + + +(my-assert + (alphanumericp #\#) + nil) + +;;; digit-char + + +(my-assert + (digit-char 0) + #\0) + + +(my-assert + (digit-char 10 11) + #\A) + + +(my-assert + (digit-char 10 10) + nil) + + +(my-assert + (digit-char 7) + #\7) + + +(my-assert + (digit-char 12) + nil) + + +(my-assert + (digit-char 12 16) + #\C) + + +(my-assert + (digit-char 6 2) + nil) + + +(my-assert + (digit-char 1 2) + #\1) + +;;; digit-char-p + + +(my-assert + (digit-char-p #\5) + 5) + + +(my-assert + (digit-char-p #\5 2) + nil) + + +(my-assert + (digit-char-p #\A) + nil) + + +(my-assert + (digit-char-p #\a) + nil) + + +(my-assert + (digit-char-p #\A 11) + 10) + + +(my-assert + (digit-char-p #\a 11) + 10) + + +(my-assert + (mapcar #'(lambda (radix) + (map 'list #'(lambda (x) (digit-char-p x radix)) + "059AaFGZ")) + '(2 8 10 16 36)) + ((0 NIL NIL NIL NIL NIL NIL NIL) + (0 5 NIL NIL NIL NIL NIL NIL) + (0 5 9 NIL NIL NIL NIL NIL) + (0 5 9 10 10 15 NIL NIL) + (0 5 9 10 10 15 16 35))) + +;;; graphic-char + + +(my-assert + (graphic-char-p #\G) + t) + + +(my-assert + (graphic-char-p #\#) + t) + + +(my-assert + (graphic-char-p #\Space) + t) + + +(my-assert + (graphic-char-p #\Newline) + nil) + +;;; standard-char-p + + +(my-assert + (standard-char-p #\Space) + t) + + +(my-assert + (standard-char-p #\~) + t) + +;;; char-upcase + + +(my-assert + (char-upcase #\a) + #\A) + + +(my-assert + (char-upcase #\A) + #\A) + + +(my-assert + (char-downcase #\a) + #\a) + + +(my-assert + (char-downcase #\A) + #\a) + + +(my-assert + (char-upcase #\9) + #\9) + + +(my-assert + (char-downcase #\9) + #\9) + + +(my-assert + (char-upcase #\@) + #\@) + + +(my-assert + (char-downcase #\@) + #\@) + +;; Note that this next example might run for a very long time in +;; some implementations if CHAR-CODE-LIMIT happens to be very large +;; for that implementation. + +(my-assert + (dotimes (code char-code-limit) + (let ((char (code-char code))) + (when char + (unless (cond ((upper-case-p char) + (char= (char-upcase + (char-downcase char)) char)) + ((lower-case-p char) + (char= (char-downcase + (char-upcase char)) char)) + (t (and (char= (char-upcase + (char-downcase char)) char) + (char= (char-downcase + (char-upcase char)) char)))) + (return char))))) + NIL) + +;;; upper-case-p + +(my-assert + (upper-case-p #\A) + t) + + +(my-assert + (upper-case-p #\a) + nil) + + +(my-assert + (both-case-p #\a) + t) + + +(my-assert + (both-case-p #\5) + nil) + + +(my-assert + (lower-case-p #\5) + nil) + + +(my-assert + (upper-case-p #\5) + nil) + +;;; char-code-limit + + +(my-assert + (>= char-code-limit 96) + t) + +;;; char-name + + +(my-assert + (char-name #\ ) + "Space") + + +(my-assert + (char-name #\Space) + "Space") + + +(my-assert + (char-name #\Page) + "Page") + + +(my-assert + (char-name #\a) + #+(or cmu sbcl ecls) nil + #+clisp "LATIN_SMALL_LETTER_A" + #-(or cmu sbcl clisp ecls) fill-this-in) +;; NIL OR "LOWERCASE-a" OR "Small-A" OR "LA01" + + +(my-assert + (char-name #\A) + #+(or cmu sbcl ecls) nil + #+clisp "LATIN_CAPITAL_LETTER_A" + #-(or cmu sbcl clisp ecls) fill-this-in) +;; NIL OR "UPPERCASE-A" OR "Capital-A" OR "LA02" + +;; Even though its CHAR-NAME can vary, #\A prints as #\A + +(my-assert + (prin1-to-string (read-from-string (format nil "#\\~A" (or (char-name #\A) "A")))) + "#\\A") + +;;; name-char + + +(my-assert + (name-char 'space) + #\Space) + + +(my-assert + (name-char "space") + #\Space) + + +(my-assert + (name-char "Space") + #\Space) + + + +(my-assert + (let ((x (char-name #\a))) + (or (not x) (eql (name-char x) #\a))) + t) + + + + + + + + + + + + + + + diff --git a/src/ansi-tests/section14.lisp b/src/ansi-tests/section14.lisp new file mode 100644 index 000000000..076f7a803 --- /dev/null +++ b/src/ansi-tests/section14.lisp @@ -0,0 +1,1934 @@ +;;; section 14 conses -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) +;;; cons + +(my-assert + (cons 1 2) + (1 . 2)) + +(my-assert + (cons 1 nil) + (1)) + +(my-assert + (cons nil 2) + (NIL . 2)) + +(my-assert + (cons nil nil) + (NIL)) + +(my-assert + (cons 1 (cons 2 (cons 3 (cons 4 nil)))) + (1 2 3 4)) + +(my-assert + (cons 'a 'b) + (A . B)) + +(my-assert + (cons 'a (cons 'b (cons 'c '()))) + (A B C)) + +(my-assert + (cons 'a (list 'b 'c 'd)) + (A B C D)) + + +;;; consp + +(my-assert + (consp nil) + nil) + +(my-assert + (consp (cons 1 2)) + t) + +(my-assert + (consp '()) + nil) + +(my-assert + (consp 'nil) + nil) + +;;; atom + +(my-assert + (atom 'sss) + t) + +(my-assert + (atom (cons 1 2)) + nil) + +(my-assert + (atom nil) + t) + +(my-assert + (atom '()) + t) + +(my-assert + (atom 3) + t) + +;;; rplaca + +(my-assert + (defparameter *some-list* (list* 'one 'two 'three 'four)) + *some-list*) + +(my-assert + *some-list* + (ONE TWO THREE . FOUR)) + +(my-assert + (rplaca *some-list* 'uno) + (UNO TWO THREE . FOUR)) + +(my-assert + *some-list* + (UNO TWO THREE . FOUR)) + +(my-assert + (rplacd (last *some-list*) (list 'IV)) + (THREE IV)) + +(my-assert + *some-list* + (UNO TWO THREE IV)) + +;;; copy-tree + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c)))) + (object-too object) + (copy-as-list (copy-list object)) + (copy-as-alist (copy-alist object)) + (copy-as-tree (copy-tree object))) + (list + (eq object object-too) ;; T + (eq copy-as-tree object) ;; NIL + (eql copy-as-tree object) ;; NIL + (equal copy-as-tree object) ;; T + ) + ) + (t nil nil t)) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c))))) + + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1))) + (ONE . 1)) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c))))) + + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1)) + object) + ((ONE . 1) ("two" "a" B C))) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c)))) + (object-too object)) + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1)) + object-too) + ((ONE . 1) ("two" "a" B C))) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c)))) + (copy-as-list (copy-list object))) + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1)) + copy-as-list) + ((1 . "one") ("two" "a" B C))) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c)))) + (copy-as-alist (copy-alist object))) + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1)) + copy-as-alist) + ((1 . "one") (2 "a" B C))) + +(my-assert + (let* ((object (list (cons 1 "one") + (cons 2 (list 'a 'b 'c)))) + (copy-as-tree (copy-tree object))) + (setf (first (cdr (second object))) "a" + (car (second object)) "two" + (car object) (cons 'one 1)) + copy-as-tree) + ((1 . "one") (2 A B C)) ) + +;;; sublis + +(my-assert + (sublis (list (cons 'x 100) + (cons 'z 'zprime)) + (append (list 'plus 'x + (list 'minus 'g 'z 'x 'p) + 4) + 'x)) + (PLUS 100 (MINUS G ZPRIME 100 P) 4 . 100)) + +(my-assert + (sublis (list (cons (list '+ 'x 'y) + (list '- 'x 'y)) + (cons (list '- 'x 'y) + (list '+ 'x 'y))) + (list '* + (list '/ + (list '+ 'x 'y) + (list '+ 'x 'p)) + (list '- 'x 'y)) + :test #'equal) + (* (/ (- X Y) (+ X P)) (+ X Y))) + +(my-assert + (let ((tree1 (list 1 + (list 1 2) + (list (list 1 2 3)) + (list (list (list 1 2 3 4)))))) + tree1) + (1 (1 2) ((1 2 3)) (((1 2 3 4))))) + +(my-assert + (let ((tree1 (list 1 + (list 1 2) + (list (list 1 2 3)) + (list (list (list 1 2 3 4)))))) + (sublis (list (cons 3 "three")) + tree1)) + (1 (1 2) ((1 2 "three")) (((1 2 "three" 4))))) + +(my-assert + (let ((tree1 (list 1 + (list 1 2) + (list (list 1 2 3)) + (list (list (list 1 2 3 4)))))) + (sublis (list (cons t "string")) + (sublis (list (cons 1 "") (cons 4 44)) + tree1) + :key #'stringp)) + ("string" ("string" 2) (("string" 2 3)) ((("string" 2 3 44))))) + +(my-assert + (let ((tree1 (list 1 + (list 1 2) + (list (list 1 2 3)) + (list (list (list 1 2 3 4)))))) + (sublis (list (cons 3 "three")) + tree1) + (sublis (list (cons t "string")) + (sublis (list (cons 1 "") (cons 4 44)) + tree1) + :key #'stringp) + tree1) + (1 (1 2) ((1 2 3)) (((1 2 3 4))))) + +(my-assert + (let ((tree2 (list "one" (list "one" "two") + (list (list "one" "Two" "three"))))) + tree2) + ("one" ("one" "two") (("one" "Two" "three"))) ) + +(my-assert + (let ((tree2 (list (string "one") + (list (string "one") + (string "two")) + (list (list (string "one") + (string "Two") + (string "three") + ))))) + (sublis (list (cons (copy-seq "two") + 2)) + tree2)) + ("one" ("one" "two") (("one" "Two" "three")))) + +(my-assert + (let ((tree2 (list (string "one") + (list (string "one") + (string "two") + ) + (list (list (string "one") + (string "Two") + (string "three") + ))))) + (sublis (list (cons (string "two") + 2)) + tree2) + tree2) + ("one" ("one" "two") (("one" "Two" "three"))) ) + +(my-assert + (let ((tree2 (list "one" (list "one" "two") + (list (list "one" "Two" "three"))))) + (sublis (list (cons "two" 2)) tree2 :test 'equal)) + ("one" ("one" 2) (("one" "Two" "three"))) ) + +(my-assert + (let ((tree1 (list 1 + (list 1 2) + (list (list 1 2 3)) + (list (list (list 1 2 3 4)))))) + (nsublis (list (cons t '(quote temp))) + tree1 + :key #'(lambda (x) (or (atom x) (< (list-length x) 3))))) + ((QUOTE TEMP) (QUOTE TEMP) QUOTE TEMP) ) + +;;; subst + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + tree1) + (1 (1 2) (1 2 3) (1 2 3 4))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (subst "two" 2 tree1)) + (1 (1 "two") (1 "two" 3) (1 "two" 3 4))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (subst "five" 5 tree1)) + (1 (1 2) (1 2 3) (1 2 3 4))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (eq tree1 (subst "five" 5 tree1))) + #+(or sbcl cmu sbcl clisp) T + #+ecls nil + #-(or sbcl cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (subst 'tempest 'hurricane + (list 'shakespeare 'wrote (list 'the 'hurricane))) + (SHAKESPEARE WROTE (THE TEMPEST))) + +(my-assert + (subst 'foo 'nil (list 'shakespeare 'wrote (list 'twelfth 'night))) + (SHAKESPEARE WROTE (TWELFTH NIGHT . FOO) . FOO)) + +(my-assert + (subst (cons 'a 'cons) + (cons 'old 'pair) + (list (cons 'old 'spice) + (append (list (cons 'old 'shoes) 'old) + 'pair) + (cons 'old 'pair)) + :test #'equal) + ((OLD . SPICE) ((OLD . SHOES) A . CONS) (A . CONS))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (subst-if 5 #'listp tree1)) + 5) + +(subst-if-not (list 'x) + #'consp + (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (subst-if-not (list 'x) #'consp tree1)) + ;(1 (X)) + ((X) ((X) (X) X) ((X) (X) (X) X) ((X) (X) (X) (X) X) X)) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (subst-if-not (list 'x) #'consp tree1) + tree1) + (1 (1 2) (1 2 3) (1 2 3 4))) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (nsubst 'x 3 tree1 :key #'(lambda (y) (and (listp y) (third y))))) + (1 (1 2) X X)) + +(my-assert + (let ((tree1 (list 1 (list 1 2) (list 1 2 3) (list 1 2 3 4)))) + (nsubst 'x 3 tree1 :key #'(lambda (y) (and (listp y) (third y)))) + tree1) + (1 (1 2) X X)) + +;;; tree-equal + +(my-assert + (let ((tree1 (list 1 (list 1 2))) + (tree2 (list 1 (list 1 2)))) + tree2) + (1 (1 2))) + +(my-assert + (let ((tree1 (list 1 (list 1 2))) + (tree2 (list 1 (list 1 2)))) + (tree-equal tree1 tree2)) + t) + +(my-assert + (let ((tree1 (list 1 (list 1 2))) + (tree2 (list 1 (list 1 2)))) + (eql tree1 tree2)) + nil) + +(my-assert + (let ((tree1 (list ''a (list ''b ''c))) + (tree2 (list ''a (list ''b ''c)))) + tree2) + ('a ('b 'c)) ) + +(my-assert + (let ((tree1 (list ''a (list ''b ''c))) + (tree2 (list ''a (list ''b ''c)))) + (tree-equal tree1 tree2 :test 'eq)) + t) + +;;; copy-list + +(my-assert + (let ((lst (list 1 (list 2 3)))) + lst) + (1 (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst)) + slst) + (1 (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + clst) + (1 (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (eq slst lst)) + t) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (eq clst lst)) + nil) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (equal clst lst)) + t) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one")) + ("one" (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + slst) + ("one" (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + clst) + (1 (2 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + (setf (caadr lst) "two")) + "two") + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + (setf (caadr lst) "two") + lst) + ("one" ("two" 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + (setf (caadr lst) "two") + slst) + ("one" ("two" 3))) + +(my-assert + (let* ((lst (list 1 (list 2 3))) + (slst lst) + (clst (copy-list lst))) + (rplaca lst "one") + (setf (caadr lst) "two") + clst) + (1 ("two" 3))) + +;;; list list* + +(my-assert + (list 1) + (1)) + +(my-assert + (list* 1) + 1) + +(my-assert + (let (( a 1)) + a) + 1) + +(my-assert + (let (( a 1)) + (list a 2)) + (1 2)) + +(my-assert + (let (( a 1)) + (list 'a '2)) + (A 2)) + +(my-assert + (let (( a 1)) + (list 'a 2)) + (A 2)) + +(my-assert + (let (( a 1)) + (list* a 2)) + (1 . 2)) + +(my-assert + (list) + NIL) + +(my-assert + (let ((a (list 1 2))) + a) + (1 2)) + +(my-assert + (let ((a (list 1 2))) + (eq a (list* a))) + t) + +(my-assert + (let ((a (list 1 2))) + (list 3 4 'a (car (cons 'b 'c)) (+ 6 -2))) + (3 4 A B 4)) + +(my-assert + (let ((a (list 1 2))) + (list* 'a 'b 'c 'd)) + (A B C . D)) + +(my-assert + (cons 'a (cons 'b (cons 'c 'd))) + (A B C . D)) + +(my-assert + (list* 'a 'b 'c (list 'd 'e 'f)) + (A B C D E F)) + +;;; list-length + +(my-assert + (list-length (list 'a 'b 'c 'd)) + 4) + +(my-assert + (list-length (list 'a (list 'b 'c) 'd)) + 3) + +(my-assert + (list-length '()) + 0) + +(my-assert + (list-length nil) + 0) + +(my-assert + (defun circular-list (&rest elements) + (let ((cycle (copy-list elements))) + (nconc cycle cycle))) + CIRCULAR-LIST) + +(my-assert + (list-length (circular-list 'a 'b)) + NIL) + +(my-assert + (list-length (circular-list 'a)) + NIL) + +(my-assert + (list-length (circular-list)) + 0) + +;;; listp + +(my-assert + (listp nil) + t) + +(my-assert + (listp (cons 1 2)) + t) + +(my-assert + (listp (make-array 6)) + nil) + +(my-assert + (listp t) + nil) + +;;; make-list + +(my-assert + (make-list 5) + (NIL NIL NIL NIL NIL)) + +(my-assert + (make-list 3 :initial-element 'rah) + (RAH RAH RAH)) + +(my-assert + (make-list 2 :initial-element (list 1 2 3)) + ((1 2 3) (1 2 3))) + +(my-assert + (make-list 0) + NIL) ;i.e., ()) + +(my-assert + (make-list 0 :initial-element 'new-element) + NIL ) + +;;; push + +(my-assert + (let ((llst (list nil))) + llst) + (NIL)) + +(my-assert + (let ((llst (list nil))) + (push 1 (car llst))) + (1)) + +(my-assert + (let ((llst (list nil))) + (push 1 (car llst)) + llst) + ((1))) + +(my-assert + (let ((llst (list nil))) + (push 1 (car llst)) + (push 1 (car llst))) + (1 1)) + +(my-assert + (let ((llst (list nil))) + (push 1 (car llst)) + (push 1 (car llst)) + llst) + ((1 1))) + +(my-assert + (let ((x (list 'a + (list 'b 'c) + 'd))) + x) + (A (B C) D)) + +(my-assert + (let ((x (list 'a + (list 'b 'c) + 'd))) + (push 5 (cadr x))) + (5 B C) ) + +(my-assert + (let ((x (list 'a + (list 'b 'c) + 'd))) + (push 5 (cadr x)) + x) + (A (5 B C) D)) + +;;; pop + +(my-assert + (let ((stack (list 'a 'b 'c))) + stack) + (A B C)) + +(my-assert + (let ((stack (list 'a 'b 'c))) + (pop stack)) + A) + +(my-assert + (let ((stack (list 'a 'b 'c))) + (pop stack) + stack) + (B C)) + +(my-assert + (let ((llst (list (list 1 2 3 4)))) + llst) + ((1 2 3 4))) + +(my-assert + (let ((llst (list (list 1 2 3 4)))) + (pop (car llst))) + 1) + +(my-assert + (let ((llst (list (list 1 2 3 4)))) + (pop (car llst)) + llst) + ((2 3 4))) + +;;; nth + +(my-assert + (nth 0 (list 'foo 'bar 'baz)) + FOO) + +(my-assert + (nth 1 (list 'foo 'bar 'baz)) + BAR) + +(my-assert + (nth 3 (list 'foo 'bar 'baz)) + NIL) + +(my-assert + (let ((0-to-3 (list 0 1 2 3))) + 0-to-3) + (0 1 2 3)) + +(my-assert + (let ((0-to-3 (list 0 1 2 3))) + (setf (nth 2 0-to-3) "two")) + "two") + +(my-assert + (let ((0-to-3 (list 0 1 2 3))) + (setf (nth 2 0-to-3) "two") + 0-to-3) + (0 1 "two" 3)) + +;;; endp + +(my-assert + (endp nil) + t) + +(my-assert + (endp (list 1 2)) + nil) + +(my-assert + (endp (cddr (list 1 2))) + t) + +;;; null + +(my-assert + (null '()) + T) + +(my-assert + (null nil) + T) + +(my-assert + (null t) + NIL) + +(my-assert + (null 1) + NIL) + +;;; nconc + +(my-assert + (nconc) + NIL) + +(my-assert + (setq x (list 'a 'b 'c)) + (A B C)) + +(my-assert + (setq y (list 'd 'e 'f)) + (D E F)) + +(my-assert + (nconc x y) + (A B C D E F)) + +(my-assert + x + (A B C D E F)) + +(my-assert + (setq foo (list 'a 'b 'c 'd 'e) + bar (list 'f 'g 'h 'i 'j) + baz (list 'k 'l 'm)) + (K L M)) + +(my-assert + (setq foo (nconc foo bar baz)) + (A B C D E F G H I J K L M)) + +(my-assert + foo + (A B C D E F G H I J K L M)) + +(my-assert + bar + (F G H I J K L M)) + +(my-assert + baz + (K L M)) + +(my-assert + (setq foo (list 'a 'b 'c 'd 'e) + bar (list 'f 'g 'h 'i 'j) + baz (list 'k 'l 'm)) + (K L M)) + +(my-assert + (setq foo (nconc nil foo bar nil baz)) + (A B C D E F G H I J K L M) ) + +(my-assert + foo + (A B C D E F G H I J K L M)) + +(my-assert + bar + (F G H I J K L M)) + +(my-assert + baz + (K L M)) + +;;; append + +(my-assert + (append (list 'a 'b 'c) + (list 'd 'e 'f) + '() + (list 'g)) + (A B C D E F G)) + +(my-assert + (append (list 'a 'b 'c) + 'd) + (A B C . D)) + +(my-assert + (setq lst (list 'a 'b 'c)) + (A B C)) + +(my-assert + (append lst (list 'd)) + (A B C D)) + +(my-assert + lst + (A B C)) + +(my-assert + (append) + NIL) + +(my-assert + (append 'a) + A) + +;;; revappend + +(my-assert + (let ((list-1 (list 1 2 3)) + (list-2 (list 'a 'b 'c))) + (list (revappend list-1 list-2) + (equal list-1 (list 1 2 3)) + (equal list-2 (list 'a 'b 'c)))) + ((3 2 1 A B C) T T)) + + +(my-assert + (revappend (list 1 2 3) '()) + (3 2 1)) + +(my-assert + (revappend (list 1 2 3) + (cons 'a 'b)) + (3 2 1 A . B)) + +(my-assert + (revappend '() + (list 'a 'b 'c)) + (A B C)) + +(my-assert + (revappend (list 1 2 3) + 'a) + (3 2 1 . A)) + +(my-assert + (revappend '() 'a) + A ) ;degenerate case) + +(my-assert + (let ((list-1 (copy-list (list 1 2 3))) + (list-2 (list 'a 'b 'c))) + (list (nreconc list-1 list-2) + (equal list-1 (list 1 2 3)) + (equal list-2 (list 'a 'b 'c)))) + ((3 2 1 A B C) NIL T)) + + +;;; butlast + +(my-assert + (setq lst (list 1 2 3 4 5 6 7 8 9)) + (1 2 3 4 5 6 7 8 9)) + +(my-assert + (butlast lst) + (1 2 3 4 5 6 7 8)) + +(my-assert + (butlast lst 5) + (1 2 3 4)) + +(my-assert + (butlast lst (+ 5 5)) + NIL) + +(my-assert + lst + (1 2 3 4 5 6 7 8 9)) + +(my-assert + (nbutlast lst 3) + (1 2 3 4 5 6)) + +(my-assert + lst + (1 2 3 4 5 6)) + +(my-assert + (nbutlast lst 99) + NIL) + +(my-assert + lst + (1 2 3 4 5 6)) + +(my-assert + (butlast (list 'a 'b 'c 'd)) + (A B C)) + +(my-assert + (butlast (list (list 'a 'b) + (list 'c 'd))) + ((A B))) + +(my-assert + (butlast (list 'a)) + NIL) + +(my-assert + (butlast nil) + NIL) + +(my-assert + (setq foo (list 'a 'b 'c 'd)) + (A B C D)) + +(my-assert + (nbutlast foo) + (A B C)) + +(my-assert + foo + (A B C)) + +(my-assert + (nbutlast (list 'a)) + NIL) + +(my-assert + (nbutlast '()) + NIL) + +;;; last + +(my-assert + (last nil) + NIL) + +(my-assert + (last (list 1 2 3)) + (3)) + +(my-assert + (last (append (list 1 2) + 3)) + (2 . 3)) + +(my-assert + (setq x (list 'a 'b 'c 'd)) + (A B C D)) + +(my-assert + (last x) + (D)) + +(my-assert + (progn + (rplacd (last x) (list 'e 'f)) + t) + t) + +(my-assert + x + (A B C D E F)) + +(my-assert + (last x) + (F)) + +(my-assert + (last (list 'a 'b 'c)) + (C)) + +(my-assert + (last (list 'a 'b 'c) 0) + ()) + +(my-assert + (last (list 'a 'b 'c) 1) + (C)) + +(my-assert + (last (list 'a 'b 'c) 2) + (B C)) + +(my-assert + (last (list 'a 'b 'c) 3) + (A B C)) + +(my-assert + (last (list 'a 'b 'c) 4) + (A B C)) + +(my-assert + (last (cons 'a 'b) 0) + B) + +(my-assert + (last (cons 'a 'b) 1) + (A . B)) + +(my-assert + (last (cons 'a 'b) 2) + (A . B)) + +;;; nthcdr + +(my-assert + (nthcdr 0 '()) + NIL) + +(my-assert + (nthcdr 3 '()) + NIL) + +(my-assert + (nthcdr 0 (list 'a 'b 'c)) + (A B C)) + +(my-assert + (nthcdr 2 (list 'a 'b 'c)) + (C)) + +(my-assert + (nthcdr 4 (list 'a 'b 'c)) + ()) + +(my-assert + (nthcdr 1 (cons 0 1)) + 1) + +(my-assert + (locally (declare (optimize (safety 3))) + (nthcdr 3 (cons 0 1))) + TYPE-ERROR) + +;;; rest + +(my-assert + (rest (list 1 2)) + (2)) + +(my-assert + (rest (cons 1 2)) + 2) + +(my-assert + (rest (list 1)) + NIL) + +(my-assert + (setq *cons* (cons 1 2)) + (1 . 2)) + +(my-assert + (setf (rest *cons*) "two") + "two") + +(my-assert + *cons* + (1 . "two")) + +;;; member + +(my-assert + (member 2 (list 1 2 3)) + (2 3)) + +(my-assert + (member 2 (list (cons 1 2) + (cons 3 4)) + :test-not #'= + :key #'cdr) + ((3 . 4))) + +(my-assert + (member 'e (list 'a 'b 'c 'd)) + NIL) + +(my-assert + (member-if #'listp (list 'a 'b nil 'c 'd)) + (NIL C D)) + +(my-assert + (member-if #'numberp (list 'a #\Space 5/3 'foo)) + (5/3 FOO)) + +(my-assert + (member-if-not #'zerop + (append (list 3 6 9 11) + 12) + :key #'(lambda (x) (mod x 3))) + (11 . 12)) + +;;; mapc and co + +(my-assert + (mapcar #'car (list (list 1 'a) + (list 2 'b) + (list 3 'c))) + (1 2 3) ) + +(my-assert + (mapcar #'abs (list 3 -4 2 -5 -6)) + (3 4 2 5 6)) + +(my-assert + (mapcar #'cons (list 'a 'b 'c) (list 1 2 3)) + ((A . 1) (B . 2) (C . 3))) + +(my-assert + (maplist #'append (list 1 2 3 4) (list 1 2) (list 1 2 3)) + ((1 2 3 4 1 2 1 2 3) (2 3 4 2 2 3))) + +(my-assert + (maplist #'(lambda (x) (cons 'foo x)) (list 'a 'b 'c 'd)) + ((FOO A B C D) (FOO B C D) (FOO C D) (FOO D))) + +(my-assert + (maplist #'(lambda (x) (if (member (car x) (cdr x)) 0 1)) + (list 'a 'b 'a 'c 'd 'b 'c)) + (0 0 1 0 1 1 1)) + +(my-assert + (setq dummy nil) + NIL ) + +(my-assert + (mapc #'(lambda (&rest x) (setq dummy (append dummy x))) + (list 1 2 3 4) + (list 'a 'b 'c 'd 'e) + (list 'x 'y 'z)) + (1 2 3 4) ) + +(my-assert + dummy + (1 A X 2 B Y 3 C Z) ) + +(my-assert + (setq dummy nil) + NIL ) + +(my-assert + (mapl #'(lambda (x) (push x dummy)) + (list 1 2 3 4)) + (1 2 3 4) ) + +(my-assert + dummy + ((4) (3 4) (2 3 4) (1 2 3 4)) ) + +(my-assert + (mapcan #'(lambda (x y) (if (null x) nil (list x y))) + (list nil nil nil 'd 'e) + (list 1 2 3 4 5 6)) + (D 4 E 5) ) + +(my-assert + (mapcan #'(lambda (x) (and (numberp x) (list x))) + (list 'a 1 'b 'c 3 4 'd 5)) + (1 3 4 5)) + +(my-assert + (mapcon #'list (list 1 2 3 4)) + ((1 2 3 4) (2 3 4) (3 4) (4)) ) + + +;;; acons + +(my-assert + (setq alist '()) + NIL) + +(my-assert + (acons 1 "one" alist) + ((1 . "one"))) + +(my-assert + alist + NIL) + +(my-assert + (setq alist (acons 1 "one" (acons 2 "two" alist))) + ((1 . "one") (2 . "two"))) + +(my-assert + (assoc 1 alist) + (1 . "one")) + +(my-assert + (setq alist (acons 1 "uno" alist)) + ((1 . "uno") (1 . "one") (2 . "two"))) + +(my-assert + (assoc 1 alist) + (1 . "uno")) + +;;; assoc + +(my-assert + (setq values + (list (cons 'x 100) + (cons 'y 200) + (cons 'z 50))) + ((X . 100) (Y . 200) (Z . 50))) + +(my-assert + (assoc 'y values) + (Y . 200)) + +(my-assert + (rplacd (assoc 'y values) 201) + (Y . 201)) + +(my-assert + (assoc 'y values) + (Y . 201)) + +(my-assert + (setq alist + (list (cons 1 "one") + (cons 2 "two") + (cons 3 "three"))) + ((1 . "one") (2 . "two") (3 . "three"))) + +(my-assert + (assoc 2 alist) + (2 . "two")) + +(my-assert + (assoc-if #'evenp alist) + (2 . "two")) + +(my-assert + (assoc-if-not #'(lambda(x) (< x 3)) alist) + (3 . "three")) + +(my-assert + (setq alist (list (cons "one" 1) + (cons "two" 2))) + (("one" . 1) ("two" . 2))) + +(my-assert + (assoc "one" alist) + NIL) + +(my-assert + (assoc "one" alist :test #'equalp) + ("one" . 1)) + +(my-assert + (assoc "two" alist :key #'(lambda(x) (char x 2))) + NIL ) + +(my-assert + (assoc #\o alist :key #'(lambda(x) (char x 2))) + ("two" . 2)) + +(my-assert + (assoc 'r (list (cons 'a 'b) + (cons 'c 'd) + (cons 'r 'x) + (cons 's 'y) + (cons 'r 'z))) + (R . X)) + +(my-assert + (assoc 'goo (list (cons 'foo 'bar) + (cons 'zoo 'goo))) + NIL) + +(my-assert + (assoc '2 (list (list 1 'a 'b 'c) + (list 2 'b 'c 'd) + (list -7 'x 'y 'z))) + (2 B C D)) + +(my-assert + (setq alist (list (cons "one" 1) + (cons "2" 2) + (cons "three" 3))) + (("one" . 1) ("2" . 2) ("three" . 3))) + +(my-assert + (assoc-if-not #'alpha-char-p alist + :key #'(lambda (x) (char x 0))) + ("2" . 2)) + +;;; copy-alist + +(my-assert + (progn + (defparameter *alist* (acons 1 "one" (acons 2 "two" '()))) + t) + t) + +(my-assert + *alist* + ((1 . "one") (2 . "two"))) + +(my-assert + (progn + (defparameter *list-copy* (copy-list *alist*)) + t) + t) + +(my-assert + *list-copy* + ((1 . "one") (2 . "two"))) + +(my-assert + (progn + (defparameter *alist-copy* (copy-alist *alist*)) + t) + t) + +(my-assert + *alist-copy* + ((1 . "one") (2 . "two"))) + +(my-assert + (setf (cdr (assoc 2 *alist-copy*)) "deux") + "deux") + +(my-assert + *alist-copy* + ((1 . "one") (2 . "deux"))) + +(my-assert + *alist* + ((1 . "one") (2 . "two"))) + +(my-assert + (setf (cdr (assoc 1 *list-copy*)) "uno") + "uno") + +(my-assert + *list-copy* + ((1 . "uno") (2 . "two"))) + +(my-assert + *alist* + ((1 . "uno") (2 . "two"))) + +;;; pairlis + +(my-assert + (setq keys (list 1 2 3) + data (list "one" "two" "three") + alist (list (cons 4 "four"))) + ((4 . "four"))) + +(my-assert + (pairlis keys data) + ((3 . "three") (2 . "two") (1 . "one"))) + +(my-assert + (pairlis keys data alist) + ((3 . "three") (2 . "two") (1 . "one") (4 . "four"))) + +(my-assert + alist + ((4 . "four"))) + +;;; rassoc + +(my-assert + (setq alist (list (cons 1 "one") + (cons 2 "two") + (cons 3 3))) + ((1 . "one") (2 . "two") (3 . 3))) + +(my-assert + (rassoc 3 alist) + (3 . 3)) + +(my-assert + (rassoc "two" alist) + NIL) + +(my-assert + (rassoc "two" alist :test 'equal) + (2 . "two")) + +(my-assert + (rassoc 1 alist :key #'(lambda (x) (if (numberp x) (/ x 3)))) + (3 . 3)) + +(my-assert + (rassoc 'a + (list (cons 'a 'b) + (cons 'b 'c) + (cons 'c 'a) + (cons 'z 'a))) + (C . A)) + +(my-assert + (rassoc-if #'stringp alist) + (1 . "one")) + +(my-assert + (rassoc-if-not #'vectorp alist) + (3 . 3)) + +;;; get-properties + +(my-assert + (setq x '()) + NIL) + +(my-assert + (setq *indicator-list* (list 'prop1 'prop2)) + (PROP1 PROP2)) + +(my-assert + (getf x 'prop1) + NIL) + +(my-assert + (setf (getf x 'prop1) 'val1) + VAL1) + +(my-assert + (eq (getf x 'prop1) 'val1) + t) + +(my-assert + (multiple-value-bind (a b c) + (get-properties x *indicator-list*) + (list a b c)) + (PROP1 VAL1 (PROP1 VAL1))) + +(my-assert + x + (PROP1 VAL1)) + +;;; getf + +(my-assert + (setq x '()) + NIL) + +(my-assert + (getf x 'prop1) + NIL) + +(my-assert + (getf x 'prop1 7) + 7) + +(my-assert + (getf x 'prop1) + NIL) + +(my-assert + (setf (getf x 'prop1) 'val1) + VAL1) + +(my-assert + (eq (getf x 'prop1) 'val1) + t) + +(my-assert + (getf x 'prop1) + VAL1) + +(my-assert + (getf x 'prop1 7) + VAL1) + +(my-assert + x + (PROP1 VAL1)) + +;;; remf + +(my-assert + (setq x (cons () ())) + (NIL)) + +(my-assert + (setf (getf (car x) 'prop1) 'val1) + VAL1) + +(my-assert + (remf (car x) 'prop1) + t) + +(my-assert + (remf (car x) 'prop1) + nil) + +;;; intersection + +(my-assert + (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" (string #\B) "C" "d")) + (list2 (list 1 4 5 'b 'c 'd "a" (string #\B) "c" "D"))) + (intersection list1 list2)) + #-clisp + (C B 4 1 1) + #+clisp + (1 1 4 B C)) + +(my-assert + (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" (string #\B) "C" "d")) + (list2 (list 1 4 5 'b 'c 'd "a" (string #\B) "c" "D"))) + (intersection list1 list2 :test 'equal)) + #-clisp + ("B" C B 4 1 1) + #+clisp + (1 1 4 B C "B")) + +(my-assert + (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" "B" "C" "d")) + (list2 (list 1 4 5 'b 'c 'd "a" "B" "c" "D"))) + (intersection list1 list2 :test #'equalp)) + #-clisp + ("d" "C" "B" "A" C B 4 1 1) + #+clisp + (1 1 4 B C "A" "B" "C" "d")) + +(my-assert + (let ((list1 (list 1 1 2 3 4 'a 'b 'c "A" "B" "C" "d")) + (list2 (list 1 4 5 'b 'c 'd "a" "B" "c" "D"))) + (nintersection list1 list2)) + #-clisp + (C B 4 1 1) + #+clisp + (1 1 4 B C)) + ;(1 1 4 B C)) + +(my-assert + (let ((list1 (copy-list (list (cons 1 2) + (cons 2 3) + (cons 3 4) + (cons 4 5)))) + (list2 (copy-list (list (cons 1 3) + (cons 2 4) + (cons 3 6) + (cons 4 8))))) + (nintersection list1 list2 :key #'cdr)) + #+(or sbcl cmu) ((3 . 4) (2 . 3)) + #-(or sbcl cmu) ((2 . 3) (3 . 4)) ) + +;;; adjoin + +(my-assert + (setq slist '()) + NIL ) + +(my-assert + (adjoin 'a slist) + (A) ) + +(my-assert + slist + NIL ) + +(my-assert + (setq slist (adjoin (list 'test-item + '1) + slist)) + ((TEST-ITEM 1)) ) + +(my-assert + (adjoin (list 'test-item 1) + slist) + ((TEST-ITEM 1) (TEST-ITEM 1)) ) + +(my-assert + (adjoin (list 'test-item 1) + slist + :test 'equal) + ((TEST-ITEM 1)) ) + +(my-assert + (adjoin (list 'new-test-item 1) + slist + :key #'cadr) + ((TEST-ITEM 1)) ) + +(my-assert + (adjoin (list 'new-test-item 1) + slist) + ((NEW-TEST-ITEM 1) (TEST-ITEM 1)) ) + +;;; pushnew + +(my-assert + (setq x (list 'a (list 'b 'c) 'd)) + (A (B C) D)) + +(my-assert + (pushnew 5 (cadr x)) + (5 B C) ) + +(my-assert + x + (A (5 B C) D)) + +(my-assert + (pushnew 'b (cadr x)) + (5 B C) ) + +(my-assert + x + (A (5 B C) D)) + +(my-assert + (setq lst (list (list 1) + (list 1 2) + (list 1 2 3))) + ((1) (1 2) (1 2 3))) + +(my-assert + (pushnew (list 2) lst) + ((2) (1) (1 2) (1 2 3))) + +(my-assert + (pushnew (list 1) lst) + ((1) (2) (1) (1 2) (1 2 3))) + +(my-assert + (pushnew (list 1) lst :test 'equal) + ((1) (2) (1) (1 2) (1 2 3))) + +(my-assert + (pushnew (list 1) lst :key #'car) + ((1) (2) (1) (1 2) (1 2 3)) ) + +;;; set-difference + +(my-assert + (let ((lst1 (mapcar #'string (list #\A #\b #\C #\d))) + (lst2 (mapcar #'string (list #\a #\B #\C #\d)))) + (set-difference lst1 lst2)) + #-clisp + ("d" "C" "b" "A") + #+clisp + ("A" "b" "C" "d")) + +(my-assert + (let ((lst1 (list "A" "b" "C" "d")) + (lst2 (list "a" "B" "C" "d"))) + (set-difference lst1 lst2 :test 'equal)) + #-clisp + ("b" "A") + #+clisp + ("A" "b")) + +(my-assert + (let ((lst1 (list "A" "b" "C" "d")) + (lst2 (list "a" "B" "C" "d"))) + (set-difference lst1 lst2 :test #'equalp)) + NIL ) + +(my-assert + (let ((lst1 (list "A" "b" "C" "d")) + (lst2 (list "a" "B" "C" "d"))) + (nset-difference lst1 lst2 :test #'string=)) + #+(or sbcl cmu) + ("b" "A") + #-(or sbcl cmu) + ("A" "b")) + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-difference lst1 lst2 :test #'string= :key #'cdr)) + #+(or sbcl cmu) + (("e" . "f") ("c" . "d")) + #-(or sbcl cmu) + (("c" . "d") ("e" . "f"))) + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-difference lst1 lst2 :test #'string= :key #'cdr) + lst1) + #+(or sbcl cmu) (("a" . "b") ("c" . "d")) + #-(or sbcl cmu) (("a" . "b") ("c" . "d") ("e" . "f")) ) + + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-difference lst1 lst2 :test #'string= :key #'cdr) + lst2) + (("c" . "a") ("e" . "b") ("d" . "a")) ) + +;; Remove all flavor names that contain "c" or "w". +(my-assert + (set-difference (list + "strawberry" "chocolate" "banana" + "lemon" "pistachio" "rhubarb") + '(#\c #\w) + :test #'(lambda (s c) (find c s))) + #+(or sbcl cmu) ("rhubarb" "lemon" "banana") + #+clisp ("banana" "lemon" "rhubarb") + #-(or sbcl cmu sbcl clisp) ("banana" "rhubarb" "lemon")) +;;One possible ordering.) + +;;; set-exclusive-or + +(my-assert + (let ((lst1 (list 1 (string #\a) (string #\b))) + (lst2 (list 1 (string #\A) (string #\b)))) + (set-exclusive-or lst1 lst2)) + #-clisp + ("b" "A" "b" "a") + #+clisp + ("a" "b" "A" "b")) + +(my-assert + (let ((lst1 (list 1 (string #\a) (string #\b))) + (lst2 (list 1 (string #\A) (string #\b)))) + (set-exclusive-or lst1 lst2 :test #'equal)) + ("A" "a")) + +(my-assert + (let ((lst1 (list 1 (string #\a) (string #\b))) + (lst2 (list 1 (string #\A) (string #\b)))) + (set-exclusive-or lst1 lst2 :test 'equalp)) + NIL ) + +(my-assert + (let ((lst1 (list 1 (string #\a) (string #\b))) + (lst2 (list 1 (string #\A) (string #\b)))) + (nset-exclusive-or lst1 lst2)) + ("a" "b" "A" "b") ) + + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-exclusive-or lst1 lst2 :test #'string= :key #'cdr)) + (("c" . "d") ("e" . "f") ("c" . "a") ("d" . "a"))) + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-exclusive-or lst1 lst2 :test #'string= :key #'cdr) + lst1) + #-(or sbcl cmu) (("a" . "b") ("c" . "d") ("e" . "f")) + #+(or sbcl cmu) (("a" . "b") ("c" . "d") ("e" . "f") ("c" . "a") ("d" . "a"))) + +(my-assert + (let ((lst1 (list (cons "a" "b") + (cons "c" "d") + (cons "e" "f"))) + (lst2 (list (cons "c" "a") + (cons "e" "b") + (cons "d" "a")))) + (nset-exclusive-or lst1 lst2 :test #'string= :key #'cdr) + lst2) + (("c" . "a") ("d" . "a"))) + +;;; subsetp + +(my-assert + (setq cosmos (list 1 "a" (list 1 2))) + (1 "a" (1 2))) + +(my-assert + (subsetp (list 1) cosmos) + t) + +(my-assert + (subsetp (list (list 1 2)) cosmos) + nil) + +(my-assert + (subsetp (list (list 1 2)) cosmos :test 'equal) + t) + +(my-assert + (subsetp (list 1 "A") cosmos :test #'equalp) + t) + +(my-assert + (subsetp (list (list 1) (list 2)) + (list (list 1) (list 2))) + nil) + +(my-assert + (subsetp (list (list 1) (list 2)) + (list (list 1) (list 2)) :key #'car) + t) + +;;; union + +(my-assert + (union (list 'a 'b 'c) (list 'f 'a 'd)) + #+(or sbcl cmu) (C B F A D) + #+(or clisp ecls) (B C F A D) + #-(or sbcl cmu sbcl clisp ecls) fill-this-in) + +;; (A B C F D) OR (B C F A D) OR (D F A B C) + +(my-assert + (union (list (list 'x 5) + (list 'y 6)) + (list (list 'z 2) + (list 'x 4)) + :key #'car) + #+(or sbcl cmu sbcl clisp ecls) ((Y 6) (Z 2) (X 4)) + #-(or sbcl cmu sbcl clisp ecls) fill-this-in) +;; ((X 5) (Y 6) (Z 2)) OR ((X 4) (Y 6) (Z 2)) + +(my-assert + (let ((lst1 (list 1 2 (list 1 2) "a" "b")) + (lst2 (list 2 3 (list 2 3) "B" "C"))) + (nunion lst1 lst2)) + #+(or sbcl cmu) + ("b" "a" (1 2) 1 2 3 (2 3) "B" "C") + #+(or clisp ecls) + (1 (1 2) "a" "b" 2 3 (2 3) "B" "C") + #-(or sbcl cmu sbcl clisp ecls) + fill-this-in) + +;; (1 (1 2) "a" "b" 2 3 (2 3) "B" "C") OR (1 2 (1 2) "a" "b" "C" "B" (2 3) 3) + + + + + + + + + + + diff --git a/src/ansi-tests/section15.lisp b/src/ansi-tests/section15.lisp new file mode 100644 index 000000000..7c2d19d90 --- /dev/null +++ b/src/ansi-tests/section15.lisp @@ -0,0 +1,766 @@ +;;; section 15: arrays -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(my-assert + (subtypep 'simple-array 'array) + t) + +;;; make-array + +(my-assert + (make-array 4 :initial-element nil) + #(NIL NIL NIL NIL)) + +(my-assert + (make-array '(2 4) + :element-type '(unsigned-byte 2) + :initial-contents '((0 1 2 3) (3 2 1 0))) + #2A((0 1 2 3) (3 2 1 0))) + +(my-assert + (make-array 6 + :element-type 'character + :initial-element #\a + :fill-pointer 3) + "aaa") + +(my-assert + (progn + (setq a (make-array '(4 3))) + t) + t) + +(my-assert + (dotimes (i 4) + (dotimes (j 3) + (setf (aref a i j) (list i 'x j '= (* i j))))) + NIL) + +(my-assert + (progn + (setq b (make-array 8 :displaced-to a + :displaced-index-offset 2)) + t) + t) + +(my-assert + (let ((a '())) + (dotimes (i 8) + (setq a (append a (list i (aref b i))))) + a) + (0 (0 X 2 = 0) + 1 (1 X 0 = 0) + 2 (1 X 1 = 1) + 3 (1 X 2 = 2) + 4 (2 X 0 = 0) + 5 (2 X 1 = 2) + 6 (2 X 2 = 4) + 7 (3 X 0 = 0))) + +(my-assert + (progn + (setq a1 (make-array 50)) + t) + t) + +(my-assert + (progn + (setq b1 (make-array 20 :displaced-to a1 :displaced-index-offset 10)) + t) + t) + +(my-assert + (length b1) + 20) + +(my-assert + (progn + (setq a2 (make-array 50 :fill-pointer 10)) + t) + t) + +(my-assert + (progn + (setq b2 (make-array 20 :displaced-to a2 :displaced-index-offset 10)) + t) + t) + +(my-assert + (length a2) + 10) + +(my-assert + (length b2) + 20) + +(my-assert + (progn + (setq a3 (make-array 50 :fill-pointer 10)) + t) + t) + +(my-assert + (progn + (setq b3 (make-array 20 :displaced-to a3 :displaced-index-offset 10 + :fill-pointer 5)) + t) + t) + +(my-assert + (length a3) + 10) + +(my-assert + (length b3) + 5) + + +;;; adjust-array + +(my-assert + (adjustable-array-p + (setq ada (adjust-array + (make-array '(2 3) + :adjustable t + :initial-contents '((a b c) (1 2 3))) + '(4 6)))) + T ) + +(my-assert + (array-dimensions ada) + (4 6) ) + +(my-assert + (aref ada 1 1) + 2 ) + +(my-assert + (setq beta (make-array '(2 3) :adjustable t)) + #+(or cmu sbcl) #2A((0 0 0) (0 0 0)) + #-(or cmu sbcl) #2A((NIL NIL NIL) (NIL NIL NIL))) + +(my-assert + (adjust-array beta '(4 6) :displaced-to ada) + #+(or cmu sbcl) #2A((A B C 0 0 0) + (1 2 3 0 0 0) + (0 0 0 0 0 0) + (0 0 0 0 0 0)) + #-(or cmu sbcl) #2A((A B C NIL NIL NIL) + (1 2 3 NIL NIL NIL) + (NIL NIL NIL NIL NIL NIL) + (NIL NIL NIL NIL NIL NIL))) + +(my-assert + (array-dimensions beta) + (4 6)) + +(my-assert + (aref beta 1 1) + 2 ) + +(my-assert + (let ((m + (make-array '(4 4) + :adjustable t + :initial-contents + '(( alpha beta gamma delta ) + ( epsilon zeta eta theta ) + ( iota kappa lambda mu ) + ( nu xi omicron pi ))))) + m) + #2A(( alpha beta gamma delta ) + ( epsilon zeta eta theta ) + ( iota kappa lambda mu ) + ( nu xi omicron pi ))) + +(my-assert + (let ((m + (make-array '(4 4) + :adjustable t + :initial-contents + '(( alpha beta gamma delta ) + ( epsilon zeta eta theta ) + ( iota kappa lambda mu ) + ( nu xi omicron pi ))))) + (adjust-array m '(3 5) :initial-element 'baz)) + #2A(( alpha beta gamma delta baz ) + ( epsilon zeta eta theta baz ) + ( iota kappa lambda mu baz ))) + +;;; adjustable-array-p + +(my-assert + (adjustable-array-p + (make-array 5 + :element-type 'character + :adjustable t + :fill-pointer 3)) + t) + +;;; aref + +(my-assert + (aref (setq alpha (make-array 4)) 3) + #+(or cmu sbcl) 0 + #+(or clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (setf (aref alpha 3) 'sirens) + SIRENS) + +(my-assert + (aref alpha 3) + SIRENS) + +(my-assert + (aref (setq beta (make-array '(2 4) + :element-type '(unsigned-byte 2) + :initial-contents '((0 1 2 3) (3 2 1 0)))) + 1 2) + 1) + +(my-assert + (setq gamma '(0 2)) + (0 2)) + +(my-assert + (apply #'aref beta gamma) + 2) + +(my-assert + (setf (apply #'aref beta gamma) 3) + 3) + +(my-assert + (apply #'aref beta gamma) + 3) + +(my-assert + (aref beta 0 2) + 3) + +;;; array-dimension + +(my-assert + (array-dimension (make-array 4) 0) + 4) + +(my-assert + (array-dimension (make-array '(2 3)) 1) + 3) + +;;; array-dimensions + +(my-assert + (array-dimensions (make-array 4)) + (4)) + +(my-assert + (array-dimensions (make-array '(2 3))) + (2 3)) + +(my-assert + (array-dimensions (make-array 4 :fill-pointer 2)) + (4)) + +;;; array-element-type + +(my-assert + (array-element-type (make-array 4)) + T) + +(my-assert + (array-element-type (make-array 12 :element-type '(unsigned-byte 8))) + #+(or cmu sbcl clisp) (unsigned-byte 8) + #+ecls fixnum + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (array-element-type (make-array 12 :element-type '(unsigned-byte 5))) + #+(or cmu sbcl clisp) (unsigned-byte 8) + #+ecls fixnum + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (array-element-type (make-array 5 :element-type '(mod 5))) + #+(or cmu sbcl clisp) (UNSIGNED-BYTE 4) + #+ecls fixnum + #-(or cmu sbcl clisp ecls) fill-this-in) + ; (mod 5), (mod 8), fixnum, t, or any other type of which (mod 5) is a subtype. + +;;; array-has-fill-pointer + +(my-assert + (array-has-fill-pointer-p (make-array 4)) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (array-has-fill-pointer-p (make-array '(2 3))) + nil) + +(my-assert + (array-has-fill-pointer-p + (make-array 8 + :fill-pointer 2 + :initial-element 'filler)) + t) + +;;; array-displacement + +(my-assert + (progn + (setq a1 (make-array 5)) + t) + t) + +(my-assert + (progn + (setq a2 (make-array 4 :displaced-to a1 + :displaced-index-offset 1)) + t) + t) + +(my-assert + (progn + (multiple-value-bind (a b) + (array-displacement a2) + (list a b)) + t) + t) + +(my-assert + (progn + (setq a3 (make-array 2 :displaced-to a2 + :displaced-index-offset 2)) + t) + t) + +(my-assert + (progn + (array-displacement a3) + t) + t) + +;;; array-in-bounds + +(my-assert + (progn + (setq a (make-array '(7 11) :element-type 'string-char)) + t) + t) + +(my-assert + (array-in-bounds-p a 0 0) + t) + +(my-assert + (array-in-bounds-p a 6 10) + t) + +(my-assert + (array-in-bounds-p a 0 -1) + nil) + +(my-assert + (array-in-bounds-p a 0 11) + nil) + +(my-assert + (array-in-bounds-p a 7 0) + nil) + +;;; array-rank + +(my-assert + (array-rank (make-array '())) + 0) + +(my-assert + (array-rank (make-array 4)) + 1) + +(my-assert + (array-rank (make-array '(4))) + 1) + +(my-assert + (array-rank (make-array '(2 3))) + 2) + +;;; array-row-major-index + +(my-assert + (progn + (setq a (make-array '(4 7) :element-type '(unsigned-byte 8))) + t) + t) + +(my-assert + (array-row-major-index a 1 2) + 9) + +(my-assert + (array-row-major-index + (make-array '(2 3 4) + :element-type '(unsigned-byte 8) + :displaced-to a + :displaced-index-offset 4) + 0 2 1) + 9) + +;;; array-total-size + +(my-assert + (array-total-size (make-array 4)) + 4) + +(my-assert + (array-total-size (make-array 4 :fill-pointer 2)) + 4) + +(my-assert + (array-total-size (make-array 0)) + 0) + +(my-assert + (array-total-size (make-array '(4 2))) + 8) + +(my-assert + (array-total-size (make-array '(4 0))) + 0) + +(my-assert + (array-total-size (make-array '())) + 1) + +;;; arrayp + +(my-assert + (arrayp (make-array '(2 3 4) :adjustable t)) + t) + +(my-assert + (arrayp (make-array 6)) + t) + +(my-assert + (arrayp #*1011) + t) + +(my-assert + (arrayp "hi") + t) + +(my-assert + (arrayp 'hi) + nil) + +(my-assert + (arrayp 12) + nil) + +;;; fill-pointer + +(my-assert + (setq a (make-array 8 :fill-pointer 4)) + #+(or cmu sbcl) #(0 0 0 0) + #-(or cmu sbcl) #(NIL NIL NIL NIL)) + +(my-assert + (fill-pointer a) + 4) + +(my-assert + (dotimes (i (length a)) (setf (aref a i) (* i i))) + NIL) + +(my-assert + a + #(0 1 4 9)) + +(my-assert + (setf (fill-pointer a) 3) + 3) + +(my-assert + (fill-pointer a) + 3) + +(my-assert + a + #(0 1 4)) + +(my-assert + (setf (fill-pointer a) 8) + 8) + +(my-assert + a + #+(or cmu sbcl) #(0 1 4 9 0 0 0 0) + #-(or cmu sbcl) #(0 1 4 9 NIL NIL NIL NIL)) + +(my-assert + (>= ARRAY-DIMENSION-LIMIT 1024) + t) + +(my-assert + (>= ARRAY-RANK-LIMIT 8) + t) + +(my-assert + (>= ARRAY-TOTAL-SIZE-LIMIT 1024) + t) + +;;; simple-vector-p + +(my-assert + (simple-vector-p (make-array 6)) + t) + +(my-assert + (simple-vector-p "aaaaaa") + nil) + +(my-assert + (simple-vector-p (make-array 6 :fill-pointer t)) + nil) + +;;; svref + +(my-assert + (simple-vector-p (setq v (vector 1 2 'sirens))) + t) + +(my-assert + (svref v 0) + 1) + +(my-assert + (svref v 2) + SIRENS) + +(my-assert + (setf (svref v 1) 'newcomer) + NEWCOMER ) + +(my-assert + v + #(1 NEWCOMER SIRENS)) + +;;; vector + +(my-assert + (arrayp (setq v (vector 1 2 'sirens))) + t) + +(my-assert + (vectorp v) + t) + +(my-assert + (simple-vector-p v) + t ) + +(my-assert + (length v) + 3) + +;;; vector-pop + +(my-assert + (vector-push (setq fable (list 'fable)) + (setq fa (make-array 8 + :fill-pointer 2 + :initial-element 'sisyphus))) + 2 ) + +(my-assert + (fill-pointer fa) + 3 ) + +(my-assert + (eq (vector-pop fa) fable) + t) + +(my-assert + (vector-pop fa) + SISYPHUS ) + +(my-assert + (fill-pointer fa) + 1 ) + +;;; vector-push + +(my-assert + (vector-push (setq fable (list 'fable)) + (setq fa (make-array 8 + :fill-pointer 2 + :initial-element 'first-one))) + 2) + +(my-assert + (fill-pointer fa) + 3 ) + +(my-assert + (eq (aref fa 2) fable) + t) + +(my-assert + (vector-push-extend #\X + (setq aa + (make-array 5 + :element-type 'character + :adjustable t + :fill-pointer 3))) + 3) + +(my-assert + (fill-pointer aa) + 4 ) + +(my-assert + (vector-push-extend #\Y aa 4) + 4 ) + +(my-assert + (>= (array-total-size aa) 5) + t) + +(my-assert + (vector-push-extend #\Z aa 4) + 5 ) + +(my-assert + (>= (array-total-size aa) 9) + t) + +;;; vectorp + +(my-assert + (vectorp "aaaaaa") + t) + +(my-assert + (vectorp (make-array 6 :fill-pointer t)) + t) + +(my-assert + (vectorp (make-array '(2 3 4))) + nil) + +(my-assert + (vectorp #*11) + t) + +(my-assert + (vectorp #b11) + nil) + +;;; bit + +(my-assert + (bit (setq ba (make-array 8 + :element-type 'bit + :initial-element 1)) + 3) + 1) + +(my-assert + (setf (bit ba 3) 0) + 0) + +(my-assert + (bit ba 3) + 0) + +(my-assert + (sbit ba 5) + 1) + +(my-assert + (setf (sbit ba 5) 1) + 1) + +(my-assert + (sbit ba 5) + 1) + +;;; bit-and etc + +(my-assert + (bit-and (setq ba #*11101010) #*01101011) + #*01101010) + +(my-assert + (bit-and #*1100 #*1010) + #*1000 ) + +(my-assert + (bit-andc1 #*1100 #*1010) + #*0010) + +(my-assert + (setq rba (bit-andc2 ba #*00110011 t)) + #*11001000) + +(my-assert + (eq rba ba) + t) + +(my-assert + (bit-not (setq ba #*11101010)) + #*00010101) + +(my-assert + (setq rba (bit-not ba + (setq tba (make-array 8 + :element-type 'bit)))) + #*00010101) + +(my-assert + (equal rba tba) + t) + +(my-assert + (bit-xor #*1100 #*1010) + #*0110) + +;;; bit-vector-p + +(my-assert + (bit-vector-p (make-array 6 + :element-type 'bit + :fill-pointer t)) + t) + +(my-assert + (bit-vector-p #*) + t) + +(my-assert + (bit-vector-p (make-array 6)) + nil) + +;;; simple-bit-vector + +(my-assert + (simple-bit-vector-p (make-array 6)) + nil) + +(my-assert + (simple-bit-vector-p #*) + t) + + + + + + + diff --git a/src/ansi-tests/section16.lisp b/src/ansi-tests/section16.lisp new file mode 100644 index 000000000..2263e6143 --- /dev/null +++ b/src/ansi-tests/section16.lisp @@ -0,0 +1,240 @@ +;;; section 16: strings -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; simple-string-p + +(my-assert + (simple-string-p "aaaaaa") + t) + +(my-assert + (simple-string-p (make-array 6 + :element-type 'character + :fill-pointer t)) + nil) + +;;; char + +(my-assert + (setq my-simple-string (make-string 6 :initial-element #\A)) + "AAAAAA") + +(my-assert + (schar my-simple-string 4) + #\A) + +(my-assert + (setf (schar my-simple-string 4) #\B) + #\B) + +(my-assert + my-simple-string + "AAAABA") + +(my-assert + (setq my-filled-string + (make-array 6 :element-type 'character + :fill-pointer 5 + :initial-contents my-simple-string)) + "AAAAB") + +(my-assert + (char my-filled-string 4) + #\B) + +(my-assert + (char my-filled-string 5) + #\A + "char: ... + +char ignores fill pointers when accessing elements. ") + +(my-assert + (setf (char my-filled-string 3) #\C) + #\C) + +(my-assert + (setf (char my-filled-string 5) #\D) + #\D + "char: ... + +char ignores fill pointers when accessing elements. ") + +(my-assert + (setf (fill-pointer my-filled-string) 6) + 6) + +(my-assert + my-filled-string + "AAACBD") + +;;; string + +(my-assert + (string "already a string") + "already a string") + +(my-assert + (string 'elm) + "ELM") + +(my-assert + (string #\c) + "c") + +;;; string-upcase + +(my-assert + (string-upcase "abcde") + "ABCDE") + +(my-assert + (string-upcase "Dr. Livingston, I presume?") + "DR. LIVINGSTON, I PRESUME?") + +(my-assert + (string-upcase "Dr. Livingston, I presume?" :start 6 :end 10) + "Dr. LiVINGston, I presume?") + +(my-assert + (string-downcase "Dr. Livingston, I presume?") + "dr. livingston, i presume?") + +(my-assert + (string-capitalize "elm 13c arthur;fig don't") + "Elm 13c Arthur;Fig Don'T") + +(my-assert + (string-capitalize " hello ") + " Hello ") + +(my-assert + (string-capitalize "occlUDeD cASEmenTs FOreSTAll iNADVertent DEFenestraTION") + "Occluded Casements Forestall Inadvertent Defenestration") + +(my-assert + (string-capitalize 'kludgy-hash-search) + "Kludgy-Hash-Search") + +(my-assert + (string-capitalize "DON'T!") + "Don'T!") ;not "Don't!" + +(my-assert + (string-capitalize "pipe 13a, foo16c") + "Pipe 13a, Foo16c") + +(my-assert + (setq str (copy-seq "0123ABCD890a")) + "0123ABCD890a") + +(my-assert + (nstring-downcase str :start 5 :end 7) + "0123AbcD890a") + +(my-assert + str + "0123AbcD890a") + +;;; string-trim + +(my-assert + (string-trim "abc" "abcaakaaakabcaaa") + "kaaak") + +(my-assert + (string-trim '(#\Space #\Tab #\Newline) " garbanzo beans + ") + "garbanzo beans") + +(my-assert + (string-trim " (*)" " ( *three (silly) words* ) ") + "three (silly) words") + +(my-assert + (string-left-trim "abc" "labcabcabc") + "labcabcabc") + +(my-assert + (string-left-trim " (*)" " ( *three (silly) words* ) ") + "three (silly) words* ) ") + +(my-assert + (string-right-trim " (*)" " ( *three (silly) words* ) ") + " ( *three (silly) words") + +;;; string= + +(my-assert + (string= "foo" "foo") + t) + +(my-assert + (string= "foo" "Foo") + nil) + +(my-assert + (string= "foo" "bar") + nil) + +(my-assert + (string= "together" "frog" :start1 1 :end1 3 :start2 2) + t) + +(my-assert + (string-equal "foo" "Foo") + t) + +(my-assert + (string= "abcd" "01234abcd9012" :start2 5 :end2 9) + t) + +(my-assert + (string< "aaaa" "aaab") + 3) + +(my-assert + (string>= "aaaaa" "aaaa") + 4) + +(my-assert + (string-not-greaterp "Abcde" "abcdE") + 5) + +(my-assert + (string-lessp "012AAAA789" "01aaab6" :start1 3 :end1 7 + :start2 2 :end2 6) + 6) + +(my-assert + (string-not-equal "AAAA" "aaaA") + nil) + +;;; stringp + +(my-assert + (stringp "aaaaaa") + t) + +(my-assert + (stringp #\a) + nil) + +;;; make-string + +(my-assert + (make-string 10 :initial-element #\5) + "5555555555") + +(my-assert + (length (make-string 10)) + 10) + + + + + + + diff --git a/src/ansi-tests/section17.lisp b/src/ansi-tests/section17.lisp new file mode 100644 index 000000000..ba91ff430 --- /dev/null +++ b/src/ansi-tests/section17.lisp @@ -0,0 +1,846 @@ +;;; section 17: sequences -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; 17.2.1.1 + +(my-assert + (remove "FOO" '(foo bar "FOO" "BAR" "foo" "bar") :test #'equal) + (foo bar "BAR" "foo" "bar")) + +(my-assert + (remove "FOO" '(foo bar "FOO" "BAR" "foo" "bar") :test #'equalp) + (foo bar "BAR" "bar")) + +(my-assert + (remove "FOO" '(foo bar "FOO" "BAR" "foo" "bar") :test #'string-equal) + (bar "BAR" "bar")) + +(my-assert + (remove "FOO" '(foo bar "FOO" "BAR" "foo" "bar") :test #'string=) + (BAR "BAR" "foo" "bar")) + +(my-assert + (remove 1 '(1 1.0 #C(1.0 0.0) 2 2.0 #C(2.0 0.0)) :test-not #'eql) + (1)) + +(my-assert + (remove 1 '(1 1.0 #C(1.0 0.0) 2 2.0 #C(2.0 0.0)) :test-not #'=) + (1 1.0 #C(1.0 0.0))) + +(my-assert + (remove 1 '(1 1.0 #C(1.0 0.0) 2 2.0 #C(2.0 0.0)) :test (complement #'=)) + (1 1.0 #C(1.0 0.0))) + +(my-assert + (count 1 '((one 1) (uno 1) (two 2) (dos 2)) :key #'cadr) + 2) + +(my-assert + (count 2.0 '(1 2 3) :test #'eql :key #'float) + 1) + +(my-assert + (count "FOO" (list (make-pathname :name "FOO" :type "X") + (make-pathname :name "FOO" :type "Y")) + :key #'pathname-name + :test #'equal) + 2) + +;;; 17.2.2.1 + +(my-assert + (count-if #'zerop '(1 #C(0.0 0.0) 0 0.0d0 0.0s0 3)) + 4) + +(my-assert + (remove-if-not #'symbolp '(0 1 2 3 4 5 6 7 8 9 A B C D E F)) + (A B C D E F)) + +(my-assert + (remove-if (complement #'symbolp) '(0 1 2 3 4 5 6 7 8 9 A B C D E F)) + (A B C D E F)) + +(my-assert + (count-if #'zerop '("foo" "" "bar" "" "" "baz" "quux") :key #'length) + 3) + +;;; copy-seq + +(my-assert + (let ((str "a string")) + str) + "a string") + +(my-assert + (let ((str "a string")) + (equalp str (copy-seq str))) + t) + +(my-assert + (let ((str "a string")) + (eql str (copy-seq str))) + nil) + +;;; elt + +(my-assert + (let ((str "a string")) + (setq str (copy-seq "0123456789"))) + "0123456789") + +(my-assert + (let ((str "a string")) + (setq str (copy-seq "0123456789")) + (elt str 6)) + #\6) + +(my-assert + (let ((str "a string")) + (setq str (copy-seq "0123456789")) + (setf (elt str 0) #\#)) + #\#) + +(my-assert + (let ((str "a string")) + (setq str (copy-seq "0123456789")) + (setf (elt str 0) #\#) + str) + "#123456789") + +;;; fill + +(my-assert + (fill (list 0 1 2 3 4 5) '(444)) + ((444) (444) (444) (444) (444) (444))) + +(my-assert + (fill (copy-seq "01234") #\e :start 3) + "012ee") + +(my-assert + (setq x (vector 'a 'b 'c 'd 'e)) + #(A B C D E)) + +(my-assert + (fill x 'z :start 1 :end 3) + #(A Z Z D E)) + +(my-assert + x + #(A Z Z D E)) + +(my-assert + (fill x 'p) + #(P P P P P)) + +(my-assert + x + #(P P P P P)) + +;;; make-sequence + +(my-assert + (make-sequence 'list 0) + ()) + +(my-assert + (make-sequence 'string 26 :initial-element #\.) + "..........................") + +(my-assert + (make-sequence '(vector double-float) 2 + :initial-element 1d0) + #(1.0d0 1.0d0)) + +(my-assert + (make-sequence '(vector * 2) 3) + TYPE-ERROR) + +(my-assert + (make-sequence '(vector * 4) 3) + TYPE-ERROR) + +;;; subseq + +(my-assert + (let ((str (copy-seq "012345"))) + str) + "012345") + +(my-assert + (let ((str (copy-seq "012345"))) + (subseq str 2)) + "2345") + +(my-assert + (let ((str (copy-seq "012345"))) + (subseq str 3 5)) + "34") + +(my-assert + (let ((str (copy-seq "012345"))) + (setf (subseq str 4) "abc")) + "abc") + +(my-assert + (let ((str (copy-seq "012345"))) + (setf (subseq str 4) "abc") + str) + "0123ab") + +(my-assert + (let ((str (copy-seq "012345"))) + (setf (subseq str 4) "abc") + (setf (subseq str 0 2) "A")) + "A") + +(my-assert + (let ((str (copy-seq "012345"))) + (setf (subseq str 4) "abc") + (setf (subseq str 0 2) "A") + str) + "A123ab") + +;;; map + +(my-assert + (map 'string #'(lambda (x y) + (char "01234567890ABCDEF" (mod (+ x y) 16))) + '(1 2 3 4) + '(10 9 8 7)) + "AAAA") + +(my-assert + (let ((seq (map 'list #'copy-seq + '("lower" "UPPER" "" "123")))) + seq) + ("lower" "UPPER" "" "123")) + +(my-assert + (let ((seq (map 'list #'copy-seq + '("lower" "UPPER" "" "123")))) + (map nil #'nstring-upcase seq)) + NIL) + +(my-assert + (let ((seq (map 'list #'copy-seq + '("lower" "UPPER" "" "123")))) + (map nil #'nstring-upcase seq) + seq) + ("LOWER" "UPPER" "" "123")) + +(my-assert + (map 'list #'- '(1 2 3 4)) + (-1 -2 -3 -4)) + +(my-assert + (map 'string + #'(lambda (x) (if (oddp x) #\1 #\0)) + '(1 2 3 4)) + "1010") + +(my-assert + (map '(vector * 4) #'cons "abc" "de") + TYPE-ERROR) + +;;; map-into + +(my-assert + (setq a (list 1 2 3 4) b (list 10 10 10 10)) + (10 10 10 10)) + +(my-assert + (map-into a #'+ a b) + (11 12 13 14)) + +(my-assert + a + (11 12 13 14)) + +(my-assert + b + (10 10 10 10)) + +(my-assert + (setq k '(one two three)) + (ONE TWO THREE)) + +(my-assert + (map-into a #'cons k a) + ((ONE . 11) (TWO . 12) (THREE . 13) 14)) + +;;; reduce + +(my-assert + (reduce #'* '(1 2 3 4 5)) + 120) + +(my-assert + (reduce #'append '((1) (2)) :initial-value '(i n i t)) + (I N I T 1 2)) + +(my-assert + (reduce #'append '((1) (2)) :from-end t + :initial-value '(i n i t)) + (1 2 I N I T)) + +(my-assert + (reduce #'- '(1 2 3 4)) + -8) + +(my-assert + (reduce #'- '(1 2 3 4) :from-end t) + -2) + +(my-assert + (reduce #'+ '()) + 0) + +(my-assert + (reduce #'+ '(3)) + 3) + +(my-assert + (reduce #'+ '(foo)) + FOO) + +(my-assert + (reduce #'list '(1 2 3 4)) + (((1 2) 3) 4)) + +(my-assert + (reduce #'list '(1 2 3 4) :from-end t) + (1 (2 (3 4)))) + +(my-assert + (reduce #'list '(1 2 3 4) :initial-value 'foo) + ((((foo 1) 2) 3) 4)) + +(my-assert + (reduce #'list '(1 2 3 4) + :from-end t :initial-value 'foo) + (1 (2 (3 (4 foo))))) + +;;; count + +(my-assert + (count #\a "how many A's are there in here?") + 2) + +(my-assert + (count-if-not #'oddp '((1) (2) (3) (4)) :key #'car) + 2) + +(my-assert + (count-if #'upper-case-p "The Crying of Lot 49" :start 4) + 2) + +;; length + +(my-assert + (length "abc") + 3) + +(my-assert + (setq str (make-array '(3) :element-type 'character + :initial-contents "abc" + :fill-pointer t)) + "abc") + +(my-assert + (length str) + 3) + +(my-assert + (setf (fill-pointer str) 2) + 2) + +(my-assert + (length str) + 2) + +;;; reverse + +(my-assert + (setq str "abc") + "abc") + +(my-assert + (reverse str) + "cba") + +(my-assert + str + "abc") + +(my-assert + (setq str (copy-seq str)) + "abc") + +(my-assert + (nreverse str) + "cba") + +(my-assert + str + #+(or cmu sbcl clisp ecls) "cba" + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (let ((l (list 1 2 3))) + l) + (1 2 3)) + +(my-assert + (let ((l (list 1 2 3))) + (nreverse l)) + (3 2 1)) + +(my-assert + (let ((l (list 1 2 3))) + (nreverse l) + l) + #+(or cmu sbcl ecls) (1) + #+clisp (3 2 1) + #-(or cmu sbcl clisp ecls) fill-this-in) + +;;; sort + +(my-assert + (setq tester (copy-seq "lkjashd")) + "lkjashd") + +(my-assert + (sort tester #'char-lessp) + "adhjkls") + +(my-assert + (setq tester (list '(1 2 3) '(4 5 6) '(7 8 9))) + ((1 2 3) (4 5 6) (7 8 9))) + +(my-assert + (sort tester #'> :key #'car) + ((7 8 9) (4 5 6) (1 2 3))) + +(my-assert + (setq tester (list 1 2 3 4 5 6 7 8 9 0)) + (1 2 3 4 5 6 7 8 9 0)) + +(my-assert + (stable-sort tester #'(lambda (x y) (and (oddp x) (evenp y)))) + (1 3 5 7 9 2 4 6 8 0)) + +(my-assert + (sort (setq committee-data + (vector (list (list "JonL" "White") "Iteration") + (list (list "Dick" "Waters") "Iteration") + (list (list "Dick" "Gabriel") "Objects") + (list (list "Kent" "Pitman") "Conditions") + (list (list "Gregor" "Kiczales") "Objects") + (list (list "David" "Moon") "Objects") + (list (list "Kathy" "Chapman") "Editorial") + (list (list "Larry" "Masinter") "Cleanup") + (list (list "Sandra" "Loosemore") "Compiler"))) + #'string-lessp :key #'cadar) + #((("Kathy" "Chapman") "Editorial") + (("Dick" "Gabriel") "Objects") + (("Gregor" "Kiczales") "Objects") + (("Sandra" "Loosemore") "Compiler") + (("Larry" "Masinter") "Cleanup") + (("David" "Moon") "Objects") + (("Kent" "Pitman") "Conditions") + (("Dick" "Waters") "Iteration") + (("JonL" "White") "Iteration"))) + +;; Note that individual alphabetical order within `committees' +;; is preserved. + +(my-assert + (setq committee-data + (stable-sort committee-data #'string-lessp :key #'cadr)) + #((("Larry" "Masinter") "Cleanup") + (("Sandra" "Loosemore") "Compiler") + (("Kent" "Pitman") "Conditions") + (("Kathy" "Chapman") "Editorial") + (("Dick" "Waters") "Iteration") + (("JonL" "White") "Iteration") + (("Dick" "Gabriel") "Objects") + (("Gregor" "Kiczales") "Objects") + (("David" "Moon") "Objects"))) + +;;; find + +(my-assert + (find #\d "here are some letters that can be looked at" :test #'char>) + #\Space) + +(my-assert + (find-if #'oddp '(1 2 3 4 5) :end 3 :from-end t) + 3) + +(my-assert + (find-if-not #'complexp + '#(3.5 2 #C(1.0 0.0) #C(0.0 1.0)) + :start 2) + NIL) + + +;;; position + +(my-assert + (position #\a "baobab" :from-end t) + 4) + +(my-assert + (position-if #'oddp '((1) (2) (3) (4)) :start 1 :key #'car) + 2) + +(my-assert + (position 595 '()) + NIL) + +(my-assert + (position-if-not #'integerp '(1 2 3 4 5.0)) + 4) + +;;; search + +(my-assert + (search "dog" "it's a dog's life") + 7) + +(my-assert + (search '(0 1) '(2 4 6 1 3 5) :key #'oddp) + 2) + +;;; mismatch + +(my-assert + (mismatch "abcd" "ABCDE" :test #'char-equal) + 4) + +(my-assert + (mismatch '(3 2 1 1 2 3) '(1 2 3) :from-end t) + 3) + +(my-assert + (mismatch '(1 2 3) '(2 3 4) :test-not #'eq :key #'oddp) + NIL) + +(my-assert + (mismatch '(1 2 3 4 5 6) '(3 4 5 6 7) :start1 2 :end2 4) + NIL) + +;;; replace + +(my-assert + (replace (copy-seq "abcdefghij") + "0123456789" :start1 4 :end1 7 :start2 4) + "abcd456hij") + +(my-assert + (let ((lst (copy-seq "012345678"))) + lst) + "012345678") + +(my-assert + (let ((lst (copy-seq "012345678"))) + (replace lst lst :start1 2 :start2 0)) + "010123456") + +(my-assert + (let ((lst (copy-seq "012345678"))) + (replace lst lst :start1 2 :start2 0) + lst) + "010123456") + +;;; substitute + +(my-assert + (substitute #\. #\SPACE "0 2 4 6") + "0.2.4.6") + +(my-assert + (substitute 9 4 '(1 2 4 1 3 4 5)) + (1 2 9 1 3 9 5)) + +(my-assert + (substitute 9 4 '(1 2 4 1 3 4 5) :count 1) + (1 2 9 1 3 4 5)) + +(my-assert + (substitute 9 4 '(1 2 4 1 3 4 5) :count 1 :from-end t) + (1 2 4 1 3 9 5)) + +(my-assert + (substitute 9 3 '(1 2 4 1 3 4 5) :test #'>) + (9 9 4 9 3 4 5)) + +(my-assert + (substitute-if 0 #'evenp '((1) (2) (3) (4)) :start 2 :key #'car) + ((1) (2) (3) 0)) + +(my-assert + (substitute-if 9 #'oddp '(1 2 4 1 3 4 5)) + (9 2 4 9 9 4 9)) + +(my-assert + (substitute-if 9 #'evenp '(1 2 4 1 3 4 5) :count 1 :from-end t) + (1 2 4 1 3 9 5)) + +(my-assert + (setq some-things (list 'a 'car 'b 'cdr 'c)) + (A CAR B CDR C)) + +(my-assert + (nsubstitute-if "function was here" #'fboundp some-things + :count 1 :from-end t) + (A CAR B "function was here" C)) + +(my-assert + some-things + (A CAR B "function was here" C)) + +(my-assert + (setq alpha-tester (copy-seq "ab ")) + "ab ") + +(my-assert + (nsubstitute-if-not #\z #'alpha-char-p alpha-tester) + "abz") + +(my-assert + alpha-tester + "abz") + +;;; concatenate + +(my-assert + (concatenate 'string "all" " " "together" " " "now") + "all together now") + +(my-assert + (concatenate 'list "ABC" '(d e f) #(1 2 3) #*1011) + (#\A #\B #\C D E F 1 2 3 1 0 1 1)) + +(my-assert + (concatenate 'list) + NIL) + +(my-assert + (concatenate '(vector * 2) "a" "bc") + TYPE-ERROR) + +;;; merge + +(my-assert + (setq test1 (list 1 3 4 6 7)) + (1 3 4 6 7)) + +(my-assert + (setq test2 (list 2 5 8)) + (2 5 8)) + +(my-assert + (merge 'list test1 test2 #'<) + (1 2 3 4 5 6 7 8)) + +(my-assert + (setq test1 (copy-seq "BOY")) + "BOY") + +(my-assert + (setq test2 (copy-seq "nosy")) + "nosy") + +(my-assert + (merge 'string test1 test2 #'char-lessp) + "BnOosYy") + +(my-assert + (setq test1 (vector '(red . 1) '(blue . 4))) + #((RED . 1) (BLUE . 4))) + +(my-assert + (setq test2 (vector '(yellow . 2) '(green . 7))) + #((YELLOW . 2) (GREEN . 7))) + +(my-assert + (merge 'vector test1 test2 #'< :key #'cdr) + #((RED . 1) (YELLOW . 2) (BLUE . 4) (GREEN . 7))) + +(my-assert + (merge '(vector * 4) '(1 5) '(2 4 6) #'<) + TYPE-ERROR) + + +;;; remove + +(my-assert + (remove 4 '(1 3 4 5 9)) + (1 3 5 9)) + +(my-assert + (remove 4 '(1 2 4 1 3 4 5)) + (1 2 1 3 5)) + +(my-assert + (remove 4 '(1 2 4 1 3 4 5) :count 1) + (1 2 1 3 4 5)) + +(my-assert + (remove 4 '(1 2 4 1 3 4 5) :count 1 :from-end t) + (1 2 4 1 3 5)) + +(my-assert + (remove 3 '(1 2 4 1 3 4 5) :test #'>) + (4 3 4 5)) + +(my-assert + (setq lst '(list of four elements)) + (LIST OF FOUR ELEMENTS)) + +(my-assert + (setq lst2 (copy-seq lst)) + (LIST OF FOUR ELEMENTS)) + +(my-assert + (setq lst3 (delete 'four lst)) + (LIST OF ELEMENTS)) + +(my-assert + (equal lst lst2) + nil) + +(my-assert + (remove-if #'oddp '(1 2 4 1 3 4 5)) + (2 4 4)) + +(my-assert + (remove-if #'evenp '(1 2 4 1 3 4 5) :count 1 :from-end t) + (1 2 4 1 3 5)) + +(my-assert + (remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9) :count 2 :from-end t) + (1 2 3 4 5 6 8)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete 4 tester) + (1 2 1 3 5)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete 4 tester :count 1) + (1 2 1 3 4 5)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete 4 tester :count 1 :from-end t) + (1 2 4 1 3 5)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete 3 tester :test #'>) + (4 3 4 5)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete-if #'oddp tester) + (2 4 4)) + +(my-assert + (setq tester (list 1 2 4 1 3 4 5)) + (1 2 4 1 3 4 5)) + +(my-assert + (delete-if #'evenp tester :count 1 :from-end t) + (1 2 4 1 3 5)) + +(my-assert + (setq tester (list 1 2 3 4 5 6)) + (1 2 3 4 5 6)) + +(my-assert + (delete-if #'evenp tester) + (1 3 5)) + +(my-assert + tester + #+(or cmu sbcl clisp ecls) (1 3 5) + #-(or cmu sbcl clisp ecls) fill-this-in) + +(my-assert + (setq foo (list 'a 'b 'c)) + (A B C)) + +(my-assert + (setq bar (cdr foo)) + (B C)) + +(my-assert + (setq foo (delete 'b foo)) + (A C)) + +(my-assert + bar + #+(or cmu sbcl clisp ecls) (B C) + #-(or cmu sbcl clisp ecls) fill-this-in) + ; ((C))) or ... + +(my-assert + (eq (cdr foo) (car bar)) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; T or ... + + +;;; remove-duplicates + +(my-assert + (remove-duplicates "aBcDAbCd" :test #'char-equal :from-end t) + "aBcD") + +(my-assert + (remove-duplicates '(a b c b d d e)) + (A C B D E)) + +(my-assert + (remove-duplicates '(a b c b d d e) :from-end t) + (A B C D E)) + +(my-assert + (remove-duplicates '((foo #\a) (bar #\%) (baz #\A)) + :test #'char-equal :key #'cadr) + ((BAR #\%) (BAZ #\A))) + +(my-assert + (remove-duplicates '((foo #\a) (bar #\%) (baz #\A)) + :test #'char-equal :key #'cadr :from-end t) + ((FOO #\a) (BAR #\%))) + +(my-assert + (setq tester (list 0 1 2 3 4 5 6)) + (0 1 2 3 4 5 6)) + +(my-assert + (delete-duplicates tester :key #'oddp :start 1 :end 6) + (0 4 5 6)) + diff --git a/src/ansi-tests/section18-errors.lisp b/src/ansi-tests/section18-errors.lisp new file mode 100644 index 000000000..1a2ced6b9 --- /dev/null +++ b/src/ansi-tests/section18-errors.lisp @@ -0,0 +1,43 @@ +;;; section 18 hash tables -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(my-assert + (defvar *counters* (make-hash-table)) + *COUNTERS*) + +(my-assert + (multiple-value-bind (a b) + (gethash 'foo *counters*) + (list a b)) + (NIL nil)) + +(my-assert + (multiple-value-bind (a b) + (gethash 'foo *counters* 0) + (list a b)) + (0 nil)) + +(my-assert ; XXX + (defmacro how-many (obj) `(values (gethash ,obj *counters* 0))) + HOW-MANY) + +(my-assert ; XXX + (defun count-it (obj) (incf (how-many obj))) + COUNT-IT) + +(dolist (x '(bar foo foo bar bar baz)) (count-it x)) + +(my-assert + (how-many 'foo) + 2) + +(my-assert + (how-many 'bar) + 3) + +(my-assert + (how-many 'quux) + 0) + diff --git a/src/ansi-tests/section18.lisp b/src/ansi-tests/section18.lisp new file mode 100644 index 000000000..6687ef612 --- /dev/null +++ b/src/ansi-tests/section18.lisp @@ -0,0 +1,385 @@ +;;; section 18 hash tables -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(my-assert + (progn + (setq a (make-hash-table)) + t) + t) +;; # + +(my-assert + (setf (gethash 'color a) 'brown) + BROWN) + +(my-assert + (setf (gethash 'name a) 'fred) + FRED) + +(my-assert + (multiple-value-bind (a b) + (gethash 'color a) + (list a b)) + (BROWN t)) + +(my-assert + (multiple-value-bind (a b) + (gethash 'name a) + (list a b)) + ( FRED t)) + +(my-assert + (multiple-value-bind (a b) + (gethash 'pointy a) + (list a b)) + ( NIL nil)) + +;;;make-hash-table + +(my-assert + (progn + (setq table (make-hash-table)) + t) + t) +;; # + +(my-assert + (setf (gethash "one" table) 1) + 1) + +(my-assert + (multiple-value-bind (a b) + (gethash "one" table) + (list a b)) + ( NIL nil)) + +(my-assert + (progn + (setq table (make-hash-table :test 'equal)) + t) + t) + ; # + +(my-assert + (setf (gethash "one" table) 1) + 1) + +(my-assert + (multiple-value-bind (a b) + (gethash "one" table) + (list a b)) + ( 1 T)) + +(my-assert + (progn + (make-hash-table :rehash-size 1.5 :rehash-threshold 0.7) + t) + t) + ; # + +;;; hash-table-p + +(my-assert + (progn + (setq table (make-hash-table)) + t) + t) + ; # + +(my-assert + (hash-table-p table) + t) + +(my-assert + (hash-table-p 37) + nil) + +(my-assert + (hash-table-p '((a . 1) (b . 2))) + nil) + +;; hash-table-count + +(my-assert + (progn + (setq table (make-hash-table)) + t) + t) + ; # + +(my-assert + (hash-table-count table) + 0) + +(my-assert + (setf (gethash 57 table) "fifty-seven") + "fifty-seven") + +(my-assert + (hash-table-count table) + 1) + +(my-assert + (dotimes (i 100) (setf (gethash i table) i)) + NIL) + +(my-assert + (hash-table-count table) + 100) + +;;; hash-table-rehash-size + +(my-assert + (progn (setq table (make-hash-table :size 100 :rehash-size 1.4)) + t) + t) + ; # + +(my-assert + (hash-table-rehash-size table) + #-clisp 1.4 + #+clisp 1.4s0) + +;;; HASH-TABLE-REHASH-THRESHOLD + +(my-assert + (progn + (setq table (make-hash-table :size 100 :rehash-threshold 0.5)) + t) + t) + ; # + +(my-assert + (hash-table-rehash-threshold table) + #-clisp 0.5 + #+clisp 0.75s0) + + +;;; get-hash + +(my-assert + (progn + (setq table (make-hash-table)) + t) + t) + + +(my-assert + (multiple-value-bind (a b) + (gethash 1 table) + (list a b)) + (NIL nil)) + +(my-assert + (multiple-value-bind (a b) + (gethash 1 table 2) + (list a b)) + (2 nil)) + +(my-assert + (setf (gethash 1 table) "one") + "one") + +(my-assert + (setf (gethash 2 table "two") "two") + "two") + +(my-assert + (multiple-value-bind (a b) + (gethash 1 table) + (list a b)) + ("one" t)) + +(my-assert + (multiple-value-bind (a b) + (gethash 2 table) + (list a b)) + ("two" t)) + +(my-assert + (multiple-value-bind (a b) + (gethash nil table) + (list a b)) + (NIL nil)) + +(my-assert + (setf (gethash nil table) nil) + NIL) + +(my-assert + (multiple-value-bind (a b) + (gethash nil table) + (list a b)) + (NIL t)) + +(unintern '*counters*) + +(my-assert + (defvar *counters* (make-hash-table)) + *COUNTERS*) + +(my-assert + (multiple-value-bind (a b) + (gethash 'foo *counters*) + (list a b)) + (NIL nil)) + +(my-assert + (multiple-value-bind (a b) + (gethash 'foo *counters* 0) + (list a b)) + (0 nil)) + +;;; remhash + +(setq table (make-hash-table)) + +(my-assert + (setf (gethash 100 table) "C") + "C") +(my-assert + (multiple-value-bind (a b) + (gethash 100 table) + (list a b)) + ("C" t)) + +(my-assert + (remhash 100 table) + t) + +(my-assert + (multiple-value-bind (a b) + (gethash 100 table) + (list a b)) + (NIL nil)) + +(my-assert + (remhash 100 table) + nil) + +;;; maphash + +(setq table (make-hash-table)) + +(my-assert + (dotimes (i 10) (setf (gethash i table) i)) + NIL) + +(my-assert + (let ((sum-of-squares 0)) + (maphash #'(lambda (key val) + (let ((square (* val val))) + (incf sum-of-squares square) + (setf (gethash key table) square))) + table) + sum-of-squares) + 285) + +(my-assert + (hash-table-count table) + 10) + +(my-assert + (maphash #'(lambda (key val) + (when (oddp val) (remhash key table))) + table) + NIL) + +(my-assert + (hash-table-count table) + 5) + +(my-assert + (let ((a nil)) + (maphash #'(lambda (k v) (setq a (cons (list k v) a ))) table) + a) + #-clisp + ((8 64) (6 36) (4 16) (2 4) (0 0)) + #+clisp + ((0 0) (2 4) (4 16) (6 36) (8 64))) + +;;; with-hash-table-iterator + +(my-assert + (defun test-hash-table-iterator (hash-table) + (let ((all-entries '()) + (generated-entries '()) + (unique (list nil))) + (maphash #'(lambda (key value) (push (list key value) all-entries)) + hash-table) + (with-hash-table-iterator (generator-fn hash-table) + (loop + (multiple-value-bind (more? key value) (generator-fn) + (unless more? (return)) + (unless (eql value (gethash key hash-table unique)) + (error "Key ~S not found for value ~S" key value)) + (push (list key value) generated-entries)))) + (unless (= (length all-entries) + (length generated-entries) + (length (union all-entries generated-entries + :key #'car :test (hash-table-test hash-table)))) + (error "Generated entries and Maphash entries don't correspond")) + t)) + test-hash-table-iterator) + +(my-assert + (test-hash-table-iterator table) + t) + +;;; clrhash + +(setq table (make-hash-table)) + +(my-assert + (dotimes (i 100) (setf (gethash i table) (format nil "~R" i))) + NIL) + +(my-assert + (hash-table-count table) + 100) + +(my-assert + (multiple-value-bind (a b) + (gethash 57 table) + (list a b)) + ("fifty-seven" t)) + +(clrhash table) + +(my-assert + (hash-table-count table) + 0) + +(my-assert + (multiple-value-bind (a b) + (gethash 57 table) + (list a b)) + ( NIL nil)) + +;;; sxhash + +(my-assert + (= (sxhash (list 'list "ab")) (sxhash (list 'list "ab"))) + t) + + +(my-assert + (= (sxhash "a") (sxhash (make-string 1 :initial-element #\a))) + t) + + +(my-assert + (let ((r (make-random-state))) + (= (sxhash r) (sxhash (make-random-state r)))) + t) + + + + + + + + + diff --git a/src/ansi-tests/section19.lisp b/src/ansi-tests/section19.lisp new file mode 100644 index 000000000..c30bcf82d --- /dev/null +++ b/src/ansi-tests/section19.lisp @@ -0,0 +1,6 @@ +;;; section 19: filenames -*- mode: lisp -*- +(in-package :cl-user) + + +;; nothing that meaningfull to test... + diff --git a/src/ansi-tests/section2.lisp b/src/ansi-tests/section2.lisp new file mode 100644 index 000000000..0d50293ab --- /dev/null +++ b/src/ansi-tests/section2.lisp @@ -0,0 +1,162 @@ +;;; 2.1.4.5.1 examples of mutiple escape characters -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(my-assert + (eq 'abc 'ABC) + T) + +(my-assert + (eq 'abc '|ABC|) + T) + +(my-assert + (eq 'abc 'a|B|c) + T) + +(my-assert + (eq 'abc '|abc|) + nil) + +;;; 2.1.4.6.1 +(my-assert + (eq 'abc '\A\B\C) + T) + +(my-assert + (eq 'abc 'a\Bc) + T) + +(my-assert + (eq 'abc '\ABC) + T) + +(my-assert + (eq 'abc '\abc) + nil) + +;;; 2.1.4.7.1 +(my-assert + (length '(this-that)) + 1) + +(my-assert + (length '(this - that)) + 3) + +(my-assert + (length '(a + b)) + 2) + +(my-assert + (+ 34) + 34) + +(my-assert + (+ 3 4) + 7) + +;;; 2.4.1 + +(my-assert + (cons 'this-one 'that-one) + (this-one . that-one)) + + +;;; 2.4.3.1 + +(my-assert + 'foo + FOO) + +(my-assert + ''foo + (QUOTE FOO)) + +(my-assert + (car ''foo) + QUOTE) + +;;; 2.4.4.1 + +(my-assert + (+ 3 ; three + 4) + 7) + +;;; 2.4.8.7 + +(my-assert + #B1101 + 13 ) + +(my-assert + #b101/11 + 5/3) + +;;; 2.4.8.8 +(my-assert + #o37/15 + 31/13) + +(my-assert + #o777 + 511) + +(my-assert + #o105 + 69) + +;;; 2.4.8.9 +(my-assert + #xF00 + 3840 ) + +(my-assert + #x105 + 261 ) + +;;; 2.4.8.10 +(my-assert + #2r11010101 + 213) + +(my-assert + #b11010101 + 213) + +(my-assert + #b+11010101 + 213) + +(my-assert + #o325 + 213) + +(my-assert + #xD5 + 213) + +(my-assert + #16r+D5 + 213) + +(my-assert + #o-300 + -192) + +(my-assert + #3r-21010 + -192) + +(my-assert + #25R-7H + -192) + +(my-assert + #xACCEDED + 181202413) + + diff --git a/src/ansi-tests/section20.lisp b/src/ansi-tests/section20.lisp new file mode 100644 index 000000000..2adc76d35 --- /dev/null +++ b/src/ansi-tests/section20.lisp @@ -0,0 +1,6 @@ +;;; section 20 : files -*- mode: lisp -*- +(in-package :cl-user) + + +;;; too much trouble. too much external stuff + diff --git a/src/ansi-tests/section21.lisp b/src/ansi-tests/section21.lisp new file mode 100644 index 000000000..7230f0131 --- /dev/null +++ b/src/ansi-tests/section21.lisp @@ -0,0 +1,116 @@ +;;; section 21: streams -*- mode: lisp -*- +(in-package :cl-user) + + +(my-assert + (subtypep 'stream 't) + t) + +(my-assert + (subtypep 'broadcast-stream 'stream) + t) + +(my-assert + (subtypep 'concatenated-stream 'stream) + t) + +(my-assert + (subtypep 'echo-stream 'stream) + t) + +(my-assert + (subtypep 'file-stream 'stream) + t) + +(my-assert + (subtypep 'string-stream 'stream) + t) + +(my-assert + (subtypep 'synonym-stream 'stream) + t) + +(my-assert + (subtypep 'two-way-stream 'stream) + t) + + +;;; input-stream-p + +(my-assert + (input-stream-p *standard-input*) + t) + +(my-assert + (input-stream-p *terminal-io*) + t) + +(my-assert + (input-stream-p (make-string-output-stream)) + nil) + +(my-assert + (output-stream-p *standard-output*) + t) + +(my-assert + (output-stream-p *terminal-io*) + t) + +(my-assert + (output-stream-p (make-string-input-stream "jr")) + nil) + +;;; open-stream-p + +(my-assert + (open-stream-p *standard-input*) + t) + +;;; read-byte + +(my-assert + (with-open-file (s "/tmp/temp-bytes" + :direction :output + :element-type 'unsigned-byte) + (write-byte 101 s)) + 101) + +(my-assert + (with-open-file (s "/tmp/temp-bytes" :element-type 'unsigned-byte) + (list (read-byte s) (read-byte s nil 'eof))) + (101 EOF)) + +;;; peek-char + +(my-assert + (with-input-from-string (input-stream " 1 2 3 4 5") + (list (peek-char t input-stream) + (peek-char #\4 input-stream) + (peek-char nil input-stream))) + (#\1 #\4 #\4)) + +;;; read-char + +(my-assert + (with-input-from-string (is "0123") + (let ((a nil)) + (do ((c (read-char is) (read-char is nil 'the-end))) + ((not (characterp c))) + (setq a (cons c a))) + a)) + (#\3 #\2 #\1 #\0)) + +;;; make-concatenated-stream + +(my-assert + (read (make-concatenated-stream + (make-string-input-stream "1") + (make-string-input-stream "2"))) + 12) + + + + + + diff --git a/src/ansi-tests/section22.lisp b/src/ansi-tests/section22.lisp new file mode 100644 index 000000000..f46189b71 --- /dev/null +++ b/src/ansi-tests/section22.lisp @@ -0,0 +1,203 @@ +;;; section 22: printer -*- mode: lisp -*- +(in-package :cl-user) + + +;;; from : Raymond Toy +(my-assert + (format nil "~V,,,'-A" 10 "abc") + "abc-------") + ; 0123456789 + +(my-assert + (format nil "foo") + "foo") + +(my-assert + (setq x 5) + 5) + +(my-assert + (format nil "The answer is ~D." x) + "The answer is 5.") + +(my-assert + (format nil "The answer is ~3D." x) + "The answer is 5.") + +(my-assert + (format nil "The answer is ~3,'0D." x) + "The answer is 005.") + +(my-assert + (format nil "The answer is ~:D." (expt 47 x)) + "The answer is 229,345,007.") + +(my-assert + (setq y "elephant") + "elephant") + +(my-assert + (format nil "Look at the ~A!" y) + "Look at the elephant!") + +(my-assert + (setq n 3) + 3) + +(my-assert + (format nil "~D item~:P found." n) + "3 items found.") + +(my-assert + (format nil "~R dog~:[s are~; is~] here." n (= n 1)) + "three dogs are here.") + +(my-assert + (format nil "~R dog~:*~[s are~; is~:;s are~] here." n) + "three dogs are here.") + +(my-assert + (format nil "Here ~[are~;is~:;are~] ~:*~R pupp~:@P." n) + "Here are three puppies.") + +(my-assert + (defun foo (x) + (format nil "~6,2F|~6,2,1,'*F|~6,2,,'?F|~6F|~,2F|~F" + x x x x x x)) + FOO) + +(my-assert + (foo 3.14159) + " 3.14| 31.42| 3.14|3.1416|3.14|3.14159") + +(my-assert + (foo -3.14159) + " -3.14|-31.42| -3.14|-3.142|-3.14|-3.14159") + +(my-assert + (foo 100.0) + "100.00|******|100.00| 100.0|100.00|100.0") + +(my-assert + (foo 1234.0) + "1234.00|******|??????|1234.0|1234.00|1234.0") + +(my-assert + (foo 0.006) + " 0.01| 0.06| 0.01| 0.006|0.01|0.006") + +(my-assert + (defun foo (x) + (format nil + "~9,2,1,,'*E|~10,3,2,2,'?,,'$E|~ + ~9,3,2,-2,'%@E|~9,2E" + x x x x)) + FOO) + +(my-assert + (foo 3.14159) + " 3.14E+0| 31.42$-01|+.003E+03| 3.14E+0") + +(my-assert + (foo -3.14159) + " -3.14E+0|-31.42$-01|-.003E+03| -3.14E+0") + +(my-assert + (foo 1100.0) + " 1.10E+3| 11.00$+02|+.001E+06| 1.10E+3") + +(my-assert + (foo 1100.0L0) + #-(or cmu sbcl) " 1.10L+3| 11.00$+02|+.001L+06| 1.10L+3" + #+(or cmu sbcl) " 1.10d+3| 11.00$+02|+.001d+06| 1.10d+3") + +(my-assert + (foo 1.1E13) + "*********| 11.00$+12|+.001E+16| 1.10E+13") + +(my-assert + (foo 1.1L120) + #-(or cmu sbcl) "*********|??????????|%%%%%%%%%|1.10L+120" + #+(or cmu sbcl) "*********|??????????|%%%%%%%%%|1.10d+120") + +(my-assert + (defun foo (x) + (format nil "~9,2,1,,'*G|~9,3,2,3,'?,,'$G|~9,3,2,0,'%G|~9,2G" + x x x x)) + foo) + +(my-assert + (foo 0.0314159) + " 3.14E-2|314.2$-04|0.314E-01| 3.14E-2") + +(my-assert + (foo 0.314159) + " 0.31 |0.314 |0.314 | 0.31 ") + +(my-assert + (foo 3.14159) + " 3.1 | 3.14 | 3.14 | 3.1 ") + +(my-assert + (foo 31.4159) + " 31. | 31.4 | 31.4 | 31. ") + +(my-assert + (foo 314.159) + " 3.14E+2| 314. | 314. | 3.14E+2") + +(my-assert + (foo 3141.59) + " 3.14E+3|314.2$+01|0.314E+04| 3.14E+3") + +(my-assert + (foo 3141.59L0) + #-(or cmu sbcl) " 3.14L+3|314.2$+01|0.314L+04| 3.14L+3" + #+(or cmu sbcl) " 3.14d+3|314.2$+01|0.314d+04| 3.14d+3") + +(my-assert + (foo 3.14E12) + "*********|314.0$+10|0.314E+13| 3.14E+12") + +(my-assert + (foo 3.14L120) + #-(or cmu sbcl) "*********|?????????|%%%%%%%%%|3.14L+120" + #+(or cmu sbcl) "*********|?????????|%%%%%%%%%|3.14d+120") + +(my-assert + (format nil "~10") + "foo bar") + +(my-assert + (format nil "~10:") + " foo bar") + +(my-assert + (format nil "~10") + " foobar") + +(my-assert + (format nil "~10:") + " foobar") + +(my-assert + (format nil "~10:@") + #+(or sbcl cmu ecls) + " foo bar " + #+clisp + " foo bar " + #-(or sbcl cmu clisp ecls) + fill-this-in) + +(my-assert + (format nil "~10@") + "foobar ") + +(my-assert + (format nil "~10:@") + " foobar ") + +(my-assert + (FORMAT NIL "Written to ~A." #P"foo.bin") + "Written to foo.bin.") + diff --git a/src/ansi-tests/section3.lisp b/src/ansi-tests/section3.lisp new file mode 100644 index 000000000..6a1658731 --- /dev/null +++ b/src/ansi-tests/section3.lisp @@ -0,0 +1,1073 @@ +;;; 3.1.2.1.1.4 -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +(if (boundp 'x2q) (makunbound 'x2q) 'ok) + +(my-assert + (let ((x2q 1)) ;Binds a special variable X + (declare (special x2q)) + (let ((x2q 2)) ;Binds a lexical variable X + (+ x2q ;Reads a lexical variable X + (locally (declare (special x2q)) + x2q)))) ;Reads a special variable X + 3) + +(if (boundp 'x3q) (makunbound 'x3q) 'ok) + +(my-assert + (progn + (defun two-funs (x3q) + (list (function (lambda () x3q)) + (function (lambda (y) (setq x3q y))))) + (setq funs (two-funs 6)) + T) + T) + +(my-assert + (funcall (car funs)) + 6) + +(my-assert + (funcall (cadr funs) 43) + 43) + +(my-assert + (funcall (car funs)) + 43) + +;;; 3.1.5 +(my-assert + (progn + (defun contorted-example (f g x) + (if (= x 0) + (funcall f) + (block here + (+ 5 (contorted-example g + #'(lambda () (return-from here 4)) + (- x 1)))))) + t) + T) + +(my-assert + (contorted-example nil nil 2) + 4) + + +(my-assert + (progn + (defun contorted-example (f g x) + (if (= x 0) + (funcall g) + (block here + (+ 5 (contorted-example g + #'(lambda () (return-from here 4)) + (- x 1)))))) + t) + T) + +(my-assert + (contorted-example nil nil 2) + 9) + +;;; 3.1.6 + +(my-assert + (progn + (defun invalid-example () + (let ((y (block here #'(lambda (z) (return-from here z))))) + (if (numberp y) y (funcall y 5)))) + T) + T) + +(my-assert + (invalid-example) + CONTROL-ERROR) + +(my-assert + (progn + (defun fun1 (x) + (catch 'trap (+ 3 (fun2 x)))) + (defun fun2 (y) + (catch 'trap (* 5 (fun3 y)))) + (defun fun3 (z) + (throw 'trap z)) + T) + T) + +(my-assert + (fun1 7) + 10) + +;;; 3.3.4.1 + +(unintern 'x) + +(my-assert + (let ((x 1)) + (declare (special x)) + (let ((x 2)) + (let ((old-x x) + (x 3)) + (declare (special x)) + (list old-x x)))) + (2 3) + "The first declare is only valid in it's +block. The (let ((x 2)) is a new block, +where x is not special anymore.") + +(if (boundp 'x) (makunbound 'x) 'ok) + +(my-assert + (let ((x4q 1)) ;[1] + (declare (special x4q)) ;[2] + (let ((x4q 2)) ;[3] + (dotimes (i x4q x4q) ;[4] + (declare (special x4q))))) ;[5] + 1) + + +(if (boundp 'x) (makunbound 'x) 'ok) + +;;; 3.4.1.4.1.1 + + +(my-assert + ((lambda (&key x) x) :x 1 :y 2 :allow-other-keys t) + 1) + +(my-assert + ((lambda (&key x &allow-other-keys) x) :x 1 :y 2) + 1) + +(my-assert + ((lambda (&key) t) :allow-other-keys nil) + T) + +(my-assert + ((lambda (&key x) x) + :x 1 :y 2 :allow-other-keys t :allow-other-keys nil) + 1) + +(my-assert + ((lambda (&key x) x) ;This call is not valid + :x 1 :y 2 :allow-other-keys nil :allow-other-keys t) + PROGRAM-ERROR + "See 3.5.1.4: +If this situation occurs in a safe call, an error of type +program-error must be signaled; and in an unsafe call the +situation has undefined consequences. ");; from 3.5.1.4 + +;;; 3.4.1.6 + + +(my-assert + ((lambda (a b) (+ a (* b 3))) 4 5) + 19) + +(my-assert + ((lambda (a &optional (b 2)) (+ a (* b 3))) 4 5) + 19) + +(my-assert + ((lambda (a &optional (b 2)) (+ a (* b 3))) 4) + 10) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))) + (2 NIL 3 NIL NIL)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6) + (6 T 3 NIL NIL)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6 3) + (6 T 3 T NIL)) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) 6 3 8) + (6 T 3 T (8))) + +(my-assert + ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)) + 6 3 8 9 10 11) + (6 t 3 t (8 9 10 11))) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2) + (1 2 NIL NIL)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6) + (1 2 6 NIL)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8) + (1 2 NIL 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6 :d 8) + (1 2 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8 :c 6) + (1 2 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) :a 1 :d 8 :c 6) + (:a 1 6 8)) + +(my-assert + ((lambda (a b &key c d) (list a b c d)) :a :b :c :d) + (:a :b :d NIL)) + +(my-assert + ((lambda (a b &key ((:sea c)) d) (list a b c d)) 1 2 :sea 6) + (1 2 6 NIL)) + +(my-assert + ((lambda (a b &key ((c c)) d) (list a b c d)) 1 2 'c 6) + (1 2 6 NIL) + "3.4.1.4: ... +If the notation ((keyword-name var) init-form) is used, +then the keyword name used to match arguments to +parameters is keyword-name, which may +be a symbol in any package. ... +") + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) 1) + (1 3 NIL 1 ()) ) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) 1 2) + (1 2 NIL 1 ())) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) :c 7) + (:c 7 NIL :c ())) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) 1 6 :c 7) + (1 6 7 1 (:c 7))) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) 1 6 :d 8) + (1 6 NIL 8 (:d 8))) + +(my-assert + ((lambda (a &optional (b 3) &rest x &key c (d a)) + (list a b c d x)) 1 6 :d 8 :c 9 :d 10) + (1 6 9 8 (:d 8 :c 9 :d 10))) + +;;;; eval function + ;(let ((form2p5 nil) + ; (a2p5 nil)) + + ; (my-assert + ; (setq form2p5 '(1+ a2p5) a2p5 999) + ; 999) + + ; (my-assert + ; (eval form2p5) + ; 1000) + + ; (my-assert + ; (eval 'form2p5) + ; (1+ A2p5)) + + ; (my-assert + ; (let ((a2p5 '(this would break if eval used local value))) + ; (eval form2p5)) + ; 1000)) + +;;; quote +(my-assert + (let ((a 1)) + a) + 1) + +(my-assert + (let ((a 1)) + (quote (setq a 3))) + (SETQ A 3)) + +(my-assert + (let ((a 1)) + (quote (setq a 3))) + a) + 1) + +(my-assert + (let ((a 1)) + (quote (setq a 3))) + 'a) + A) + +(my-assert + (let ((a 1)) + (quote (setq a 3))) + ''a) + (QUOTE A) ) + +(my-assert + (let ((a 1)) + (quote (setq a 3))) + '''a) + (QUOTE (QUOTE A))) + +(my-assert + (let ((a 43)) + a) + 43) + +(my-assert + (let ((a 43)) + (list a (cons a 3))) + (43 (43 . 3))) + +(my-assert + (let ((a 43)) + (list a (cons a 3)) + (list (quote a) (quote (cons a 3)))) + (A (CONS A 3)) ) + + +(my-assert + 1 + 1) + +(my-assert + '1 + 1) + +(my-assert + '"foo" + "foo") + +(my-assert + (car '(a b)) + A) + +(my-assert + '(car '(a b)) + (CAR (QUOTE (A B)))) + +(my-assert + #(car '(a b)) + #(CAR (QUOTE (A B)))) + +(my-assert + '#(car '(a b)) + #(CAR (QUOTE (A B)))) + +;;; define-compiler-macro +(my-assert + (defun square (x) (expt x 2)) + SQUARE) + +(my-assert + (define-compiler-macro square (&whole form arg) + (if (atom arg) + `(expt ,arg 2) + (case (car arg) + (square (if (= (length arg) 2) + `(expt ,(nth 1 arg) 4) + form)) + (expt (if (= (length arg) 3) + (if (numberp (nth 2 arg)) + `(expt ,(nth 1 arg) ,(* 2 (nth 2 arg))) + `(expt ,(nth 1 arg) (* 2 ,(nth 2 arg)))) + form)) + (otherwise `(expt ,arg 2))))) + SQUARE) + +(my-assert + (square (square 3)) + 81) + +(my-assert + (macroexpand '(square x)) + (SQUARE X)) ; f + +(if (boundp 'x) (makunbound 'x) 'ok) + +(my-assert + (funcall (compiler-macro-function 'square) '(square x) nil) + (EXPT X 2)) + +(my-assert + (funcall (compiler-macro-function 'square) '(square (square x)) nil) + (EXPT X 4)) + +(my-assert + (funcall (compiler-macro-function 'square) '(funcall #'square x) nil) + (EXPT X 2) + "define-compiler-macro: +... but if the car of the actual form is the symbol funcall, +then the destructuring of the arguments +is actually performed using its cddr instead") + +;;; defmacro +(my-assert + (defmacro mac1 (a b) "Mac1 multiplies and adds" + `(+ ,a (* ,b 3))) + MAC1 ) + +(my-assert + (mac1 4 5) + 19 ) + +(my-assert + (documentation 'mac1 'function) + "Mac1 multiplies and adds" ) + +(my-assert + (defmacro mac2 (&optional (a 2 b) (c 3 d) &rest x) + `'(,a ,b ,c ,d ,x)) + MAC2 ) + +(my-assert + (mac2 6) + (6 T 3 NIL NIL) ) + +(my-assert + (mac2 6 3 8) + (6 T 3 T (8)) ) + +(my-assert + (defmacro mac3 (&whole r a &optional (b 3) &rest x &key c (d a)) + `'(,r ,a ,b ,c ,d ,x)) + MAC3 ) + +(my-assert + (mac3 1 6 :d 8 :c 9 ) + ((MAC3 1 6 :D 8 :C 9 ) 1 6 9 8 (:D 8 :C 9)) ) + +;;; part II +(my-assert + (progn + (defmacro dm1a (&whole x) `',x) + t) + t) + +(my-assert + (macroexpand '(dm1a)) + (QUOTE (DM1A))) + +(my-assert + (macroexpand '(dm1a a)) + ERROR) + +(my-assert + (progn + (defmacro dm1b (&whole x a &optional b) `'(,x ,a ,b)) + t) + t) + +(my-assert + (macroexpand '(dm1b)) + ERROR) + +(my-assert + (macroexpand '(dm1b q)) + (QUOTE ((DM1B Q) Q NIL))) + +(my-assert + (macroexpand '(dm1b q r)) + (QUOTE ((DM1B Q R) Q R))) + +(my-assert + (macroexpand '(dm1b q r s)) + ERROR) + +(my-assert + (progn + (defmacro dm2a (&whole form a b) `'(form ,form a ,a b ,b)) + t) + t) + +(my-assert + (macroexpand '(dm2a x y)) + (QUOTE (FORM (DM2A X Y) A X B Y))) + +(my-assert + (dm2a x y) + (FORM (DM2A X Y) A X B Y)) + +(my-assert + (progn + (defmacro dm2b (&whole form a (&whole b (c . d) &optional (e 5)) + &body f &environment env) + ``(,',form ,,a ,',b ,',(macroexpand c env) ,',d ,',e ,',f)) + t) + t) + + ;Note that because backquote is involved, implementations may differ + ;slightly in the nature (though not the functionality) of the expansion. + + ;(my-assert + ;(macroexpand '(dm2b x1 (((incf x2) x3 x4)) x5 x6)) + ;#+(or cmu sbcl sbcl) `((DM2B X1 (((INCF X2) X3 X4)) X5 X6) ,X1 (((INCF X2) X3 X4)) + ; (LET* ((#:G411 (+ X2 1))) + ; (SETQ X2 #:G411)) + ; (X3 X4) 5 (X5 X6)) + ;#-(or cmu sbcl sbcl) (LIST* '(DM2B X1 (((INCF X2) X3 X4)) + ; X5 X6) + ; X1 + ; '((((INCF X2) X3 X4)) (SETQ X2 (+ X2 1)) (X3 X4) 5 (X5 X6)))) + +(my-assert + (let ((x1 5)) + (macrolet ((segundo (x) `(cadr ,x))) + (dm2b x1 (((segundo x2) x3 x4)) x5 x6))) + ((DM2B X1 (((SEGUNDO X2) X3 X4)) X5 X6) + 5 (((SEGUNDO X2) X3 X4)) (CADR X2) (X3 X4) 5 (X5 X6))) + +;;; macrofunction + +(my-assert + (defmacro macfun (x) '(macro-function 'macfun)) + MACFUN ) + +(my-assert + (not (macro-function 'macfun)) + nil) + +(my-assert + (macrolet ((foo (&environment env) + (if (macro-function 'bar env) + ''yes + ''no))) + (list (foo) + (macrolet ((bar () :beep)) + (foo)))) + (NO YES)) + +;;; macroexpand + +(my-assert + (defmacro alpha (x y) `(beta ,x ,y)) + ALPHA) + +(my-assert + (defmacro beta (x y) `(gamma ,x ,y)) + BETA) + +(my-assert + (defmacro delta (x y) `(gamma ,x ,y)) + DELTA) + +(my-assert + (defmacro expand (form &environment env) + (multiple-value-bind (expansion expanded-p) + (macroexpand form env) + `(values ',expansion ',expanded-p))) + EXPAND) + +(my-assert + (defmacro expand-1 (form &environment env) + (multiple-value-bind (expansion expanded-p) + (macroexpand-1 form env) + `(values ',expansion ',expanded-p))) + EXPAND-1) + +;; Simple examples involving just the global environment +(my-assert + (multiple-value-bind (a b) + (macroexpand-1 '(alpha a b)) + (list a b)) + ((BETA A B) T)) + +(my-assert + (multiple-value-bind (a b) + (expand-1 (alpha a b)) + (list a b)) + ((BETA A B) T)) + +(my-assert + (multiple-value-bind (a b) + (macroexpand '(alpha a b)) + (list a b)) + ((GAMMA A B) T)) + +(my-assert + (multiple-value-bind (a b) + (expand (alpha a b)) + (list a b)) + ((GAMMA A B) T)) + +(my-assert + (multiple-value-bind (a b) + (macroexpand-1 'not-a-macro) + (list a b)) + (NOT-A-MACRO nil)) + +(my-assert + (multiple-value-bind (a b) + (expand-1 not-a-macro) + (list a b)) + (NOT-A-MACRO nil) ) + +(my-assert + (multiple-value-bind (a b) + (macroexpand '(not-a-macro a b)) + (list a b)) + ((NOT-A-MACRO A B) nil)) + +(my-assert + (multiple-value-bind (a b) + (expand (not-a-macro a b)) + (list a b)) + ((NOT-A-MACRO A B) nil)) + +;; Examples involving lexical environments + +(my-assert + (multiple-value-bind (n h) + (macrolet ((alpha (x y) `(delta ,x ,y))) + (macroexpand-1 '(alpha a b))) + (list n h)) + ((BETA A B) T)) + +(my-assert + (multiple-value-bind (n h) + (macrolet ((alpha (x y) `(delta ,x ,y))) + (expand-1 (alpha a b))) + (list n h)) + ((DELTA A B) T)) + +(my-assert + (multiple-value-bind (n h) + (macrolet ((alpha (x y) `(delta ,x ,y))) + (macroexpand '(alpha a b))) + (list n h)) + ((GAMMA A B) T)) + +(my-assert + (multiple-value-bind (n h) + (macrolet ((alpha (x y) `(delta ,x ,y))) + (expand (alpha a b))) + (list n h)) + ((GAMMA A B) T)) + + +(my-assert + (multiple-value-bind (n h) + (macrolet ((beta (x y) `(epsilon ,x ,y))) + (expand (alpha a b))) + (list n h)) + ((EPSILON A B) T)) + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a (first x))) + (expand a))) + (list n h)) + error + "A has been declared special, thus SYMBOL-MACROLET may not bind it") + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a-new (first x))) + (expand a-new))) + (list n h)) + ((FIRST X) T)) + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a (first x))) + (macroexpand 'a))) + (list n h)) + error + "A has been declared special, thus SYMBOL-MACROLET may not bind it") + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a-new (first x))) + (macroexpand 'a-new))) + (list n h)) + (a-new nil)) + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b (alpha x y))) + (expand-1 b)) + (list n h)) + error + "B has been declared special, thus SYMBOL-MACROLET may not bind it") + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b-new (alpha x y))) + (expand-1 b-new)) + (list n h)) + ((ALPHA X Y) T)) + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b (alpha x y))) + (expand b)) + (list n h)) + error + "B has been declared special, thus SYMBOL-MACROLET may not bind it") + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b-new (alpha x y))) + (expand b-new)) + (list n h)) + ((GAMMA X Y) T)) + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b (alpha x y)) + (a b)) + (expand-1 a)) + (list n h)) + error + "A and B have been declared special, thus SYMBOL-MACROLET may not bind them") + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b-new (alpha x y)) + (a-new b-new)) + (expand-1 a-new)) + (list n h)) + (B-NEW T)) + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b (alpha x y)) + (a b)) + (expand a)) + (list n h)) + error + "A and B have been declared special, thus SYMBOL-MACROLET may not bind them") + +(my-assert + (multiple-value-bind (n h) + (symbol-macrolet ((b-new (alpha x y)) + (a-new b-new)) + (expand a-new)) + (list n h)) + ((GAMMA X Y) T)) + +;; Examples of shadowing behavior +(my-assert + (multiple-value-bind (n h) + (flet ((beta (x y) (+ x y))) + (expand (alpha a b))) + (list n h)) + ((BETA A B) T)) + +(my-assert + (multiple-value-bind (n h) + (macrolet ((alpha (x y) `(delta ,x ,y))) + (flet ((alpha (x y) (+ x y))) + (expand (alpha a b)))) + (list n h)) + ((ALPHA A B) nil)) + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a (first x))) + (let ((a x)) + (expand a)))) + (list n h)) + error + "A has been declared special, thus SYMBOL-MACROLET may not bind it") + +(my-assert + (multiple-value-bind (n h) + (let ((x (list 1 2 3))) + (symbol-macrolet ((a-new (first x))) + (let ((a-new x)) + (expand a-new)))) + (list n h)) + (a-new nil)) + +;;; define-symbol-macro +(my-assert + (defvar *things* (list 'alpha 'beta 'gamma)) + *THINGS*) + +(my-assert + (fboundp 'define-symbol-macro) + T + "The macro DEFINE-SYMBOL-MACRO should exist") + +(my-assert + (define-symbol-macro thing1 (first *things*)) + THING1) + +(my-assert + (define-symbol-macro thing2 (second *things*)) + THING2) + +(my-assert + (define-symbol-macro thing3 (third *things*)) + THING3) + +(my-assert + thing1 + ALPHA) + +(my-assert + (setq thing1 'ONE) + ONE) + +(my-assert + *things* + (ONE BETA GAMMA)) + +(my-assert + (multiple-value-setq (thing2 thing3) (values 'two 'three)) + TWO) + +(my-assert + thing3 + THREE) + +(my-assert + *things* + (ONE TWO THREE)) + +(my-assert + (list thing2 (let ((thing2 2)) thing2)) + (TWO 2)) + +;;; *macrexpand-hook* + +(my-assert + (defun hook (expander form env) + (format t "Now expanding: ~S~%" form) + (funcall expander form env)) + HOOK ) + +(my-assert + (defmacro machook (x y) `(/ (+ ,x ,y) 2)) + MACHOOK ) + +(my-assert + (macroexpand '(machook 1 2)) + (/ (+ 1 2) 2)) ; true + +(my-assert + (let ((*macroexpand-hook* #'hook)) (macroexpand '(machook 1 2))) + (/ (+ 1 2) 2)) ; true + +;;; special opperator + +(my-assert + (special-operator-p 'if) + T) + +(my-assert + (special-operator-p 'car) + nil) + +(my-assert + (special-operator-p 'one) + nil) + + +(my-assert + (special-operator-p 'block) + T) + +(my-assert + (special-operator-p 'let*) + T) + +(my-assert + (special-operator-p 'return-from) + T) + +(my-assert + (special-operator-p 'catch) + T) + +(my-assert + (special-operator-p 'load-time-value) + T) + +(my-assert + (special-operator-p 'setq) + T) + +(my-assert + (special-operator-p 'eval-when) + T) + +(my-assert + (special-operator-p 'locally) + T + "locally is a special operator") + +(my-assert + (special-operator-p 'symbol-macrolet) + T) + +(my-assert + (special-operator-p 'flet) + T) + +(my-assert + (special-operator-p 'macrolet) + T) + +(my-assert + (special-operator-p 'tagbody) + T) + +(my-assert + (special-operator-p 'function) + T) + +(my-assert + (special-operator-p 'multiple-value-call) + T) + +(my-assert + (special-operator-p 'the) + T) + +(my-assert + (special-operator-p 'go) + T) + +(my-assert + (special-operator-p 'multiple-value-prog1) + T) + +(my-assert + (special-operator-p 'throw) + T) + +(my-assert + (special-operator-p 'progn) + T) + +(my-assert + (special-operator-p 'unwind-protect) + T) + +(my-assert + (special-operator-p 'labels) + T) + +(my-assert + (special-operator-p 'progv) + T) + +(my-assert + (special-operator-p 'let) + T) + +(my-assert + (special-operator-p 'quote) + T) + +;;; constantp + +(my-assert + (constantp 1) + T) + +(my-assert + (constantp 'temp) + nil) + +(my-assert + (constantp ''temp) + t) + +(my-assert + (defconstant this-is-a-constant 'never-changing) + THIS-IS-A-CONSTANT ) + +(my-assert + (constantp 'this-is-a-constant) + t) + +(my-assert + (constantp "temp") + t) + +(my-assert + (let ((a 6)) + a) + 6 ) + +(my-assert + (let ((a 6)) + (constantp a)) + t) + +(my-assert + (constantp (values 37 Pi 'foo)) + #+(or cmu sbcl sbcl clisp ecls) t + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + + +(my-assert + (constantp '(sin pi)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(car '(x))) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(eql x x)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(typep x 'nil)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(typep x 't)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(values this-is-a-constant)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(values 'x 'y)) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + +(my-assert + (constantp '(let ((a '(a b c))) (+ (length a) 6))) + #+(or cmu sbcl sbcl clisp ecls) nil + #-(or cmu sbcl sbcl clisp ecls) FILL-THIS-IN) + + + + + + + + + diff --git a/src/ansi-tests/section4.lisp b/src/ansi-tests/section4.lisp new file mode 100644 index 000000000..1ac85a1e0 --- /dev/null +++ b/src/ansi-tests/section4.lisp @@ -0,0 +1,355 @@ +;;; types -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;coerce +(my-assert + (coerce '(a b c) 'vector) + #(A B C)) + +(my-assert + (coerce '(a b c) 'list) + (A B C)) + +(my-assert + (coerce '(#\A #\B #\C) 'string) + "ABC") + +(my-assert + (coerce #(a b c) 'vector) + #(A B C)) + +(my-assert + (coerce #(a b c) 'list) + (A B C)) + +(my-assert + (coerce #(#\A #\B #\C) 'string) + "ABC") + +(my-assert + (coerce "ABC" 'vector) + #(#\A #\B #\C)) + +(my-assert + (coerce "ABC" 'list) + (#\A #\B #\C)) + +(my-assert + (coerce "ABC" 'string) + "ABC") + +(my-assert + (coerce '(a b c) '(vector * 3)) + #(A B C)) + +(my-assert + (coerce '(a b c) 'list) + (A B C)) + +(my-assert + (coerce '(#\A #\B #\C) '(string 3)) + "ABC") + +(my-assert + (coerce #(a b c) '(vector * 3)) + #(A B C)) + +(my-assert + (coerce #(a b c) 'list) + (A B C)) + +(my-assert + (coerce #(#\A #\B #\C) '(string 3)) + "ABC") + +(my-assert + (coerce "ABC" '(vector * 3)) + #(#\A #\B #\C)) + +(my-assert + (coerce "ABC" 'list) + (#\A #\B #\C)) + +(my-assert + (coerce "ABC" '(string 3)) + "ABC") + +(my-assert + (coerce 'a 'character) + #\A) + +(my-assert + (coerce 4.56 'complex) + #C(4.56 0.0)) + +(my-assert + (coerce 4.5s0 'complex) + #C(4.5s0 0.0s0)) + +(my-assert + (coerce 7/2 'complex) + 7/2) + +(my-assert + (coerce 0 'short-float) + 0.0s0) + +(my-assert + (coerce 3.5L0 'float) + 3.5L0) + +(my-assert + (coerce 7/2 'float) + 3.5) + +(my-assert + (coerce (cons 1 2) t) + (1 . 2)) + +(my-assert + (coerce '(a b c) '(vector * 4)) + type-error) + +(my-assert + (coerce #(a b c) '(vector * 4)) + type-error) + +(my-assert + (coerce '(a b c) '(vector * 2)) + type-error) + +(my-assert + (coerce #(a b c) '(vector * 2)) + type-error) + +(my-assert + (coerce "foo" '(string 2)) + type-error) + +(my-assert + (coerce #(#\a #\b #\c) '(string 2)) + type-error) + +(my-assert + (coerce '(0 1) '(simple-bit-vector 3)) + type-error) + +;; subtypep +(my-assert + (multiple-value-bind (a b) + (subtypep 'compiled-function 'function) + (list a b)) + (T T) + "Type COMPILED-FUNCTION + +Supertypes: + +compiled-function, function, t +... +") + +(my-assert + (multiple-value-bind (a b) + (subtypep 'null 'list) + (list a b)) + (T T)) + +(my-assert + (multiple-value-bind (a b) + (subtypep 'null 'symbol) + (list a b)) + (T T)) + +(my-assert + (multiple-value-bind (a b) + (subtypep 'integer 'string) + (list a b)) + (nil #-clisp T + #+clisp nil)) + +(my-assert + (multiple-value-bind (a b) + (subtypep '(satisfies dummy) nil) + (list a b)) + (nil #-clisp t + #+clisp nil)) + +(my-assert + (multiple-value-bind (a b) + (subtypep '(integer 1 3) '(integer 1 4)) + (list a b)) + (T T)) + +(my-assert + (multiple-value-bind (a b) + (subtypep '(member) 'nil) + (list a b)) + (T T)) ; true, true ;or false, false + +(my-assert + (multiple-value-bind (a b) + (subtypep 'nil '(member)) + (list a b)) + (T T)) ; true, true ;or false, false + +;;; type-of + +(my-assert + (type-of 'a) + SYMBOL ) + +(my-assert + (type-of '(1 . 2)) + CONS) + ; OR=> (CONS FIXNUM FIXNUM) + +(my-assert + (type-of #c(0 1)) + #-cmu COMPLEX + #+cmu (COMPLEX BIT)) + ; OR=> (COMPLEX INTEGER) + +(my-assert + (defstruct temp-struct x y z) + TEMP-STRUCT) + +(my-assert + (type-of (make-temp-struct)) + TEMP-STRUCT) + +(my-assert + (type-of "abc") + #+(or cmu sbcl clisp) + (SIMPLE-BASE-STRING 3) + #-(or cmu sbcl clisp) + STRING) + ; OR=> (STRING 3) + +(my-assert + (multiple-value-bind (a b) + (subtypep (type-of "abc") 'string) + (list a b)) + (T T)) + +(my-assert + (type-of (expt 2 40)) + BIGNUM) + ; OR=> INTEGER + ; OR=> (INTEGER 1099511627776 1099511627776) + ; OR=> SYSTEM::TWO-WORD-BIGNUM + ; OR=> FIXNUM + +(my-assert + (multiple-value-bind (a b) + (subtypep (type-of 112312) 'integer) + (list a b)) + (T T)) + +(my-assert + (defvar *foo* (make-array 5 :element-type t)) + *FOO*) + +(my-assert + (class-name (class-of *foo*)) + #+(or cmu sbcl) SIMPLE-VECTOR + #-(or cmu sbcl) VECTOR) + +(my-assert + (type-of *foo*) + #+(or cmu sbcl clisp) + (SIMPLE-VECTOR 5) + #-(or cmu sbcl clisp) + VECTOR) + ; OR=> (VECTOR T 5) + +;;; typep + +(my-assert + (typep 12 'integer) + T) + +(my-assert + (typep (1+ most-positive-fixnum) 'fixnum) + nil) + +(my-assert + (typep nil t) + t) + +(my-assert + (typep nil nil) + nil) + +(my-assert + (typep 1 '(mod 2)) + t ) + +(my-assert + (typep #c(1 1) '(complex (eql 1))) + t ) + +;; To understand this next example, you might need to refer to +;; Section 12.1.5.3 (Rule of Canonical Representation for Complex Rationals). +(my-assert + (typep #c(0 0) '(complex (eql 0))) + nil + "(upgraded-complex-part-type '(eql 0)) -> RATIONAL +a subtype of REAL. So it should work. + +12.1.5.3: +also #C(5 0) is eql to 5 + #C(5.0 0.0) is not eql to 5.0 +CMUCL bombs here because of the eql. We give two +replacement tests below: +") + +(my-assert + (typep #c(1 1) 'complex) + T + "Because #C(1 1) remains an complex") + +(my-assert + (typep #c(3/2 0) 'complex) + NIL + "Because #C(3/2 0) is eql to 3/2") + +(my-assert + (typep #c(1 0) 'complex) + NIL + "Because #c(0 0) is eql to 0") + +(my-assert + (typep #c(0.0 0.0) 'complex) + T + "Because #c(0.0 0.0) remains a complex") + +;;; type-error-datum +;;(my-assert +;;(progn +;; (defun fix-digits (condition) +;; (check-type condition type-error) +;; (let* ((digits '(zero one two three four +;; five six seven eight nine)) +;; (val (position (type-error-datum condition) digits))) +;; (if (and val (subtypep 'number (type-error-expected-type condition))) +;; (store-value 7)))) + +;; (defun foo (x) +;; (handler-bind ((type-error #'fix-digits)) +;; (check-type x number) +;; (+ x 3))) +;; t) +;;t) + +;;(my-assert +;;(foo 'seven) +;;10) + + + + + + + diff --git a/src/ansi-tests/section5.lisp b/src/ansi-tests/section5.lisp new file mode 100644 index 000000000..45659c968 --- /dev/null +++ b/src/ansi-tests/section5.lisp @@ -0,0 +1,2102 @@ +;;; section 5 -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; 5.1.1.1.1 + +(my-assert + (let ((ref2 (list '()))) + (push (progn (princ "1") 'ref1) + (car (progn (princ "2") ref2)))) + (REF1)) + +#+nil +(my-assert + (let (x) + (push (setq x (list 'a)) + (car (setq x (list 'b)))) + x) + (((A) . B))) ;possible bug in hyperspec + + +;;; apply +(my-assert + (setq f '+) + +) + +(my-assert + (apply f '(1 2)) + 3) + +(my-assert + (progn + (setq f #'-) + t) + t) + +(my-assert + (apply f '(1 2)) + -1) + +(my-assert + (apply #'max 3 5 '(2 7 3)) + 7) + +(my-assert + (apply 'cons '((+ 2 3) 4)) + ((+ 2 3) . 4)) + +(my-assert + (apply #'+ '()) + 0) + +(my-assert + (defparameter *some-list* '(a b c)) + *SOME-LIST*) + +(my-assert + (defun strange-test (&rest x) (eq x *some-list*)) + STRANGE-TEST) + +(my-assert + (apply #'strange-test *some-list*) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in ) + +;;(my-assert +;;(defun foo (size &rest keys &key double &allow-other-keys) +;; (let ((v (apply #'make-array size :allow-other-keys t keys))) +;; (if double (concatenate (type-of v) v v) v))) +;;FOO) + +;;(my-assert +;;(foo 4 :initial-contents '(a b c d) :double t) +;;#(A B C D A B C D)) + +;;; defun + +(my-assert + (defun recur (x) + (when (> x 0) + (recur (1- x)))) + RECUR ) + +(my-assert + (defun ex (a b &optional c (d 66) &rest keys &key test (start 0)) + (list a b c d keys test start)) + EX ) + +(my-assert + (ex 1 2) + (1 2 NIL 66 NIL NIL 0)) + +(my-assert + (ex 1 2 3 4 :test 'equal :start 50) + (1 2 3 4 (:TEST EQUAL :START 50) EQUAL 50)) + +(my-assert + (ex :test 1 :start 2) + (:TEST 1 :START 2 NIL NIL 0)) + +;; This function assumes its callers have checked the types of the +;; arguments, and authorizes the compiler to build in that assumption. +(my-assert + (defun discriminant (a b c) + (declare (number a b c)) + "Compute the discriminant for a quadratic equation." + (- (* b b) (* 4 a c))) + DISCRIMINANT) + +(my-assert + (discriminant 1 2/3 -2) + 76/9) + +;; This function assumes its callers have not checked the types of the +;; arguments, and performs explicit type checks before making any assumptions. + +(my-assert + (defun careful-discriminant (a b c) + "Compute the discriminant for a quadratic equation." + (check-type a number) + (check-type b number) + (check-type c number) + (locally (declare (number a b c)) + (- (* b b) (* 4 a c)))) + CAREFUL-DISCRIMINANT) + +(my-assert + (careful-discriminant 1 2/3 -2) + 76/9) + +;;; fboundp + +(my-assert + (fboundp 'car) + t) + +(my-assert + (fboundp 'nth-value) + #+(or cmu sbcl clisp) t + #-(or cmu sbcl clisp) nil) + +(my-assert + (fboundp 'with-open-file) + t) + +(my-assert + (fboundp 'unwind-protect) + t) + +(my-assert + (defun my-function (x) x) + MY-FUNCTION) + +(my-assert + (fboundp 'my-function) + t) + +(my-assert + (let ((saved-definition (symbol-function 'my-function))) + (unwind-protect (progn (fmakunbound 'my-function) + (fboundp 'my-function)) + (setf (symbol-function 'my-function) saved-definition))) + nil) + +(my-assert + (fboundp 'my-function) + t) + +(my-assert + (defmacro my-macro (x) `',x) + MY-MACRO) + +(my-assert + (fboundp 'my-macro) + t) + +(my-assert + (fmakunbound 'my-function) + MY-FUNCTION) + +(my-assert + (fboundp 'my-function) + nil) + +(my-assert + (flet ((my-function (x) x)) + (fboundp 'my-function)) + nil) + +;;; fmakunbound + +(my-assert + (defun add-some (x) (+ x 19)) + ADD-SOME) + +(my-assert + (fboundp 'add-some) + t) + +(my-assert + (flet ((add-some (x) (+ x 37))) + (fmakunbound 'add-some) + (add-some 1)) + 38) + +(my-assert + (fboundp 'add-some) + nil) + +;;; macroletjes + +(my-assert + (flet ((flet1 (n) (+ n n))) + (flet ((flet1 (n) (+ 2 (flet1 n)))) + (flet1 2))) + 6) + +(my-assert + (defun dummy-function () 'top-level) + DUMMY-FUNCTION ) + +(my-assert + (funcall #'dummy-function) + TOP-LEVEL ) + +(my-assert + (flet ((dummy-function () 'shadow)) + (funcall #'dummy-function)) + SHADOW ) + +(my-assert + (eq (funcall #'dummy-function) (funcall 'dummy-function)) + t ) + +(my-assert + (flet ((dummy-function () 'shadow)) + (eq (funcall #'dummy-function) + (funcall 'dummy-function))) + nil) + +(my-assert + (defun recursive-times (k n) + (labels ((temp (n) + (if (zerop n) 0 (+ k (temp (1- n)))))) + (temp n))) + RECURSIVE-TIMES) + +(my-assert + (recursive-times 2 3) + 6) + +(my-assert + (defmacro mlets (x &environment env) + (let ((form `(babbit ,x))) + (macroexpand form env))) + MLETS) + +(my-assert + (macrolet ((babbit (z) `(+ ,z ,z))) (mlets 5)) + 10) + +(my-assert + (flet ((safesqrt (x) (sqrt (abs x)))) + ;; The safesqrt function is used in two places. + (safesqrt (apply #'+ (map 'list #'safesqrt '(1 2 3 4 5 6))))) + 3.2911735) + +(my-assert + (defun integer-power (n k) + (declare (integer n)) + (declare (type (integer 0 *) k)) + (labels ((expt0 (x k a) + (declare (integer x a) (type (integer 0 *) k)) + (cond ((zerop k) a) + ((evenp k) (expt1 (* x x) (floor k 2) a)) + (t (expt0 (* x x) (floor k 2) (* x a))))) + (expt1 (x k a) + (declare (integer x a) (type (integer 0 *) k)) + (cond ((evenp k) (expt1 (* x x) (floor k 2) a)) + (t (expt0 (* x x) (floor k 2) (* x a)))))) + (expt0 n k 1))) + INTEGER-POWER) + +(my-assert + (defun example (y l) + (flet ((attach (x) + (setq l (append l (list x))))) + (declare (inline attach)) + (dolist (x y) + (unless (null (cdr x)) + (attach x))) + l)) + EXAMPLE) + +(my-assert + (example '((a apple apricot) (b banana) (c cherry) (d) (e)) + '((1) (2) (3) (4 2) (5) (6 3 2))) + ((1) (2) (3) (4 2) (5) (6 3 2) (A APPLE APRICOT) (B BANANA) (C CHERRY))) + + +;;; funcall + +(my-assert + (funcall #'+ 1 2 3) + 6) + +(my-assert + (funcall 'car '(1 2 3)) + 1) + +(my-assert + (funcall 'position 1 '(1 2 3 2 1) :start 1) + 4) + +(my-assert + (cons 1 2) + (1 . 2)) + +(my-assert + (flet ((cons (x y) `(kons ,x ,y))) + (let ((cons (symbol-function '+))) + (funcall #'cons + (funcall 'cons 1 2) + (funcall cons 1 2)))) + (KONS (1 . 2) 3)) + +;;; functionp + +(my-assert + (functionp 'append) + nil) + +(my-assert + (functionp #'append) + t) + +(my-assert + (functionp (symbol-function 'append)) + t) + +(my-assert + (flet ((f () 1)) (functionp #'f)) + t) + +(my-assert + (functionp (compile nil '(lambda () 259))) + t) + +(my-assert + (functionp nil) + nil) + +(my-assert + (functionp 12) + nil) + +(my-assert + (functionp '(lambda (x) (* x x))) + nil) + +(my-assert + (functionp #'(lambda (x) (* x x))) + t) + +;;; compiled-function-p + + +(my-assert + (defun f (x) x) + F) + +(my-assert + (compiled-function-p #'f) + #+(or cmu sbcl ecls) t + #+clisp nil + #-(or cmu sbcl clisp ecls) fill-this-in) +;; false OR true + +(my-assert + (compiled-function-p 'f) + nil) + +(my-assert + (compile 'f) + F) + +(my-assert + (compiled-function-p #'f) + t) + +(my-assert + (compiled-function-p 'f) + nil) + +(my-assert + (compiled-function-p (compile nil '(lambda (x) x))) + t) + +(my-assert + (compiled-function-p #'(lambda (x) x)) + #+(or cmu sbcl ecls) t + #+clisp nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; false OR true + +(my-assert + (compiled-function-p '(lambda (x) x)) + nil) + +;;; CALL-ARGUMENTS-LIMIT + +(my-assert + (>= CALL-ARGUMENTS-LIMIT 50) + t) + +;;; LAMBDA-LIST-KEYWORDS + +(my-assert + (not (member '&ALLOW-OTHER-KEYS LAMBDA-LIST-KEYWORDS)) + nil) + +(my-assert + (not (member '&AUX LAMBDA-LIST-KEYWORDS)) + nil) + +(my-assert + (not (member '&ENVIRONMENT LAMBDA-LIST-KEYWORDS)) + nil) + +(my-assert + (not (member '&OPTIONAL LAMBDA-LIST-KEYWORDS)) + nil) + +(my-assert + (not (member '&REST LAMBDA-LIST-KEYWORDS)) + nil) + +(my-assert + (not (member '&WHOLE LAMBDA-LIST-KEYWORDS)) + nil) + +;;; LAMBDA-PARAMETERS-LIMIT + +(my-assert + (>= LAMBDA-PARAMETERS-LIMIT 50) + t) + +;;; defconstant + +(my-assert + (defconstant this-is-a-constant 'never-changing "for a test") + THIS-IS-A-CONSTANT) + +(my-assert + this-is-a-constant + NEVER-CHANGING) + +(my-assert + (documentation 'this-is-a-constant 'variable) + "for a test") + +(my-assert + (constantp 'this-is-a-constant) + t) + +;;; defparameter + +(my-assert + (defparameter *p* 1) + *P*) + +(my-assert + *p* + 1) + +(my-assert + (constantp '*p*) + nil) + +(my-assert + (setq *p* 2) + 2) + +(my-assert + (defparameter *p* 3) + *P*) + +(my-assert + *p* + 3) + +(unintern '*V*) + +(my-assert + (defvar *v* 1) + *V*) + +(my-assert + *v* + 1) + +(my-assert + (constantp '*v*) + nil) + +(my-assert + (setq *v* 2) + 2) + +(my-assert + (defvar *v* 3) + *V*) + +(my-assert + *v* + 2) + +(my-assert + (defun foo () + (let ((*p* 'p) (*v* 'v)) + (bar))) + FOO) + +(my-assert + (defun bar () (list *p* *v*)) + BAR) + +(my-assert + (foo) + (P V)) + +;;; destructuring-bind + +(my-assert + (defun iota (n) (loop for i from 1 to n collect i)) ;helper + IOTA) + +(my-assert + (destructuring-bind ((a &optional (b 'bee)) one two three) + `((alpha) ,@(iota 3)) + (list a b three two one)) + (ALPHA BEE 3 2 1)) + +;;; let & let* + + ;(let ((a 'top)) + + ; (my-assert + ; (defun dummy-function () a) + ; DUMMY-FUNCTION) + + ; (my-assert + ; (let ((a 'inside) (b a)) + ; (format nil "~S ~S ~S" a b (dummy-function))) + ; "INSIDE TOP TOP" ) + + ; (my-assert + ; (let* ((a 'inside) (b a)) + ; (format nil "~S ~S ~S" a b (dummy-function))) + ; "INSIDE INSIDE TOP" )) + + ;(setf a 'top) + + ;(my-assert + ; (let ((a 'inside) (b a)) + ; (declare (special a)) + ; (format nil "~S ~S ~S" a b (dummy-function))) + ; "INSIDE TOP INSIDE") + +;;; progv + +(my-assert + (let ((*x* 3)) + (progv '(*x*) '(4) + (list *x* (symbol-value '*x*)))) + (3 4)) + +(my-assert + (setq *x* 1) + 1) + +(my-assert + (progv '(*x*) '(2) *x*) + 2) + +(my-assert + *x* + 1) + + +;;; setq +(my-assert + (setq a 1 b 2 c 3) + 3) + +(my-assert + a + 1) + +(my-assert + b + 2) + +(my-assert + c + 3) + +;; Use of SETQ to update values by sequential assignment. +(my-assert + (setq a (1+ b) b (1+ a) c (+ a b)) + 7) + +(my-assert + a + 3) + +(my-assert + b + 4) + +(my-assert + c + 7) + +;; This illustrates the use of SETQ on a symbol macro. +(my-assert + (let ((x (list 10 20 30))) + (symbol-macrolet ((y (car x)) (z (cadr x))) + (setq y (1+ z) z (1+ y)) + (list x y z))) + ((21 22 30) 21 22)) + +;;; psetq +(my-assert + (psetq a 1 b 2 c 3) + NIL) + +(my-assert + a + 1) + +(my-assert + b + 2) + +(my-assert + c + 3) + +;; Use of PSETQ to update values by parallel assignment. +;; The effect here is very different than if SETQ had been used. +(my-assert + (psetq a (1+ b) b (1+ a) c (+ a b)) + NIL) + +(my-assert + a + 3) + +(my-assert + b + 2) + +(my-assert + c + 3) + +;; Use of PSETQ on a symbol macro. +(my-assert + (let ((x (list 10 20 30))) + (symbol-macrolet ((y (car x)) (z (cadr x))) + (psetq y (1+ z) z (1+ y)) + (list x y z))) + ((21 11 30) 21 11)) + +;; Use of parallel assignment to swap values of A and B. +(my-assert + (multiple-value-bind (n h) + (let ((a 1) (b 2)) + (psetq a b b a) + (values a b)) + (list n h)) + (2 1)) + + +;;; block + +(my-assert + (block empty) + NIL) + +(my-assert + (multiple-value-bind (n h) + (block whocares (values 1 2) (values 3 4)) + (list n h)) + (3 4)) + +(my-assert + (let ((x 1)) + (block stop (setq x 2) (return-from stop) (setq x 3)) + x) + 2) + +(my-assert + (multiple-value-bind (n h) + (block early + (return-from early (values 1 2)) + (values 3 4)) + (list n h)) + (1 2)) + +(my-assert + (block outer (block inner (return-from outer 1)) 2) + 1) + +(my-assert + (block twin (block twin (return-from twin 1)) 2) + 2) + +;; Contrast behavior of this example with corresponding example of CATCH. +(my-assert + (block b + (flet ((b1 () (return-from b 1))) + (block b (b1) (print 'unreachable)) + 2)) + 1) + +;; catch + +(my-assert + (catch 'dummy-tag 1 2 (throw 'dummy-tag 3) 4) + 3) + +(my-assert + (catch 'dummy-tag 1 2 3 4) + 4) + +(my-assert + (defun throw-back (tag) (throw tag t)) + THROW-BACK) + +(my-assert + (catch 'dummy-tag (throw-back 'dummy-tag) 2) + T) + +;; Contrast behavior of this example with corresponding example of BLOCK. +(my-assert + (catch 'c + (flet ((c1 () (throw 'c 1))) + (catch 'c (c1) (print 'unreachable)) + 2)) + 2) + +;;; go +(my-assert + (tagbody + (setq val 2) + (go lp) + (incf val 3) + lp (incf val 4)) + NIL) + +(my-assert + val + 6 ) + +;;; return-from +(my-assert + (block alpha (return-from alpha) 1) + NIL) + +(my-assert + (block alpha (return-from alpha 1) 2) + 1) + +(my-assert + (multiple-value-bind (n h) + (block alpha (return-from alpha (values 1 2)) 3) + (list n h)) + (1 2)) + +(my-assert + (let ((a 0)) + (dotimes (i 10) (incf a) (when (oddp i) (return))) + a) + 2) + +(my-assert + (defun temp (x) + (if x (return-from temp 'dummy)) + 44) + TEMP) + +(my-assert + (temp nil) + 44) + +(my-assert + (temp t) + DUMMY) + +(my-assert + (block out + (flet ((exit (n) (return-from out n))) + (block out (exit 1))) + 2) + 1) + +(my-assert + (block nil + (unwind-protect (return-from nil 1) + (return-from nil 2))) + 2) + +;;; return + +(my-assert + (block nil (return) 1) + NIL) + +(my-assert + (block nil (return 1) 2) + 1) + +(my-assert + (multiple-value-bind (n h) + (block nil (return (values 1 2)) 3) + (list n h)) + (1 2)) + +(my-assert + (block nil (block alpha (return 1) 2)) + 1) + +(my-assert + (block alpha (block nil (return 1)) 2) + 2) + +(my-assert + (block nil (block nil (return 1) 2)) + 1) + +;;; tagbody + +(my-assert + (let (val) + (tagbody + (setq val 1) + (go point-a) + (incf val 16) + point-c + (incf val 04) + (go point-b) + (incf val 32) + point-a + (incf val 02) + (go point-c) + (incf val 64) + point-b + (incf val 08)) + val) + 15) + +(my-assert + (defun f1 (flag) + (let ((n 1)) + (tagbody + (setq n (f2 flag #'(lambda () (go out)))) + out + (prin1 n)))) + F1) + +(my-assert + (defun f2 (flag escape) + (if flag (funcall escape) 2)) + F2) + +(my-assert + (f1 nil) + NIL) + +(my-assert + (f1 t) + NIL) + +;;; trow + +(my-assert + (multiple-value-bind (n h) + (catch 'result + (setq i 0 j 0) + (loop (incf j 3) (incf i) + (if (= i 3) (throw 'result (values i j))))) + (list n h)) + (3 9)) + + +(my-assert + (catch nil + (unwind-protect (throw nil 1) + (throw nil 2))) + 2) + +;;; unwind-protect + +(my-assert + (defun dummy-function (x) + (setq state 'running) + (unless (numberp x) (throw 'abort 'not-a-number)) + (setq state (1+ x))) + DUMMY-FUNCTION) + +(my-assert + (catch 'abort (dummy-function 1)) + 2) + +(my-assert + state + 2) + +(my-assert + (catch 'abort (dummy-function 'trash)) + NOT-A-NUMBER) + +(my-assert + state + RUNNING) + +(my-assert + (catch 'abort (unwind-protect (dummy-function 'trash) + (setq state 'aborted))) + NOT-A-NUMBER) + +(my-assert + state + ABORTED) + +;;; not + +(my-assert + (not nil) + T) + +(my-assert + (not '()) + T) + +(my-assert + (not (integerp 'sss)) + T) + +(my-assert + (not (integerp 1)) + NIL) + +(my-assert + (not 3.7) + NIL) + +(my-assert + (not 'apple) + NIL) + +;;; eq + +(my-assert + (eq 'a 'b) + nil) + +(my-assert + (eq 'a 'a) + t) + +(my-assert + (eq 3 3) + #+(or cmu sbcl clisp ecls) t + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (eq 3 3.0) + nil) + +(my-assert + (eq 3.0 3.0) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (eq #c(3 -4) #c(3 -4)) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (eq #c(3 -4.0) #c(3 -4)) + nil) + +(my-assert + (eq (cons 'a 'b) (cons 'a 'c)) + nil) + +(my-assert + (eq (cons 'a 'b) (cons 'a 'b)) + nil) + +(my-assert + (eq '(a . b) '(a . b)) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (progn (setq x (cons 'a 'b)) (eq x x)) + T) + +(my-assert + (progn (setq x '(a . b)) (eq x x)) + T) + +(my-assert + (eq #\A #\A) + #+(or cmu sbcl clisp ecls) t + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (let ((x "Foo")) (eq x x)) + T) + +(my-assert + (eq "Foo" "Foo") + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (eq "Foo" (copy-seq "Foo")) + nil) + +(my-assert + (eq "FOO" "foo") + nil) + +(my-assert + (eq "string-seq" (copy-seq "string-seq")) + nil) + +(my-assert + (let ((x 5)) (eq x x)) + #+(or cmu sbcl clisp ecls) t + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +;;; eql + +(my-assert + (eql 'a 'b) + nil) + +(my-assert + (eql 'a 'a) + t) + +(my-assert + (eql 3 3) + t) + +(my-assert + (eql 3 3.0) + nil) + +(my-assert + (eql 3.0 3.0) + t) + +(my-assert + (eql #c(3 -4) #c(3 -4)) + t) + +(my-assert + (eql #c(3 -4.0) #c(3 -4)) + nil) + +(my-assert + (eql (cons 'a 'b) (cons 'a 'c)) + nil) + +(my-assert + (eql (cons 'a 'b) (cons 'a 'b)) + nil) + +(my-assert + (eql '(a . b) '(a . b)) + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (progn (setq x (cons 'a 'b)) (eql x x)) + t) + +(my-assert + (progn (setq x '(a . b)) (eql x x)) + t) + +(my-assert + (eql #\A #\A) + t) + +(my-assert + (eql "Foo" "Foo") + #+(or cmu sbcl clisp ecls) nil + #-(or cmu sbcl clisp ecls) fill-this-in) + ; true OR false + +(my-assert + (eql "Foo" (copy-seq "Foo")) + nil) + +(my-assert + (eql "FOO" "foo") + nil) + +;;; equal + +(my-assert + (equal 'a 'b) + nil) + +(my-assert + (equal 'a 'a) + T) + +(my-assert + (equal 3 3) + t) + +(my-assert + (equal 3 3.0) + nil) + +(my-assert + (equal 3.0 3.0) + t) + +(my-assert + (equal #c(3 -4) #c(3 -4)) + t) + +(my-assert + (equal #c(3 -4.0) #c(3 -4)) + nil) + +(my-assert + (equal (cons 'a 'b) (cons 'a 'c)) + nil) + +(my-assert + (equal (cons 'a 'b) (cons 'a 'b)) + t) + +(my-assert + (equal #\A #\A) + t) + +(my-assert + (equal #\A #\a) + nil) + +(my-assert + (equal "Foo" "Foo") + t) + +(my-assert + (equal "Foo" (copy-seq "Foo")) + t) + +(my-assert + (equal "FOO" "foo") + nil) + +(my-assert + (equal "This-string" "This-string") + t) + +(my-assert + (equal "This-string" "this-string") + nil) + +;;; equalp + +(my-assert + (equalp 'a 'b) + nil) + +(my-assert + (equalp 'a 'a) + t) + +(my-assert + (equalp 3 3) + t) + +(my-assert + (equalp 3 3.0) + t) + +(my-assert + (equalp 3.0 3.0) + t) + +(my-assert + (equalp #c(3 -4) #c(3 -4)) + t) + +(my-assert + (equalp #c(3 -4.0) #c(3 -4)) + t) + +(my-assert + (equalp (cons 'a 'b) (cons 'a 'c)) + nil) + +(my-assert + (equalp (cons 'a 'b) (cons 'a 'b)) + t) + +(my-assert + (equalp #\A #\A) + t) + +(my-assert + (equalp #\A #\a) + t) + +(my-assert + (equalp "Foo" "Foo") + t) + +(my-assert + (equalp "Foo" (copy-seq "Foo")) + t) + +(my-assert + (equalp "FOO" "foo") + t) + +(my-assert + (setq array1 (make-array 6 :element-type 'integer + :initial-contents '(1 1 1 3 5 7))) + #(1 1 1 3 5 7)) + +(my-assert + (setq array2 (make-array 8 :element-type 'integer + :initial-contents '(1 1 1 3 5 7 2 6) + :fill-pointer 6)) + #(1 1 1 3 5 7)) + +(my-assert + (equalp array1 array2) + t) + +(my-assert + (setq vector1 (vector 1 1 1 3 5 7)) + #(1 1 1 3 5 7)) + +(my-assert + (equalp array1 vector1) + t ) + +;; hashtables etc? + +;;; identity + +(my-assert + (identity 101) + 101) + +(my-assert + (mapcan #'identity (list (list 1 2 3) '(4 5 6))) + (1 2 3 4 5 6)) + +;;; complement + +(my-assert + (funcall (complement #'zerop) 1) + t) + +(my-assert + (funcall (complement #'characterp) #\A) + nil) + +(my-assert + (funcall (complement #'member) 'a '(a b c)) + nil) + +(my-assert + (funcall (complement #'member) 'd '(a b c)) + t) + + +;;; constantly + +(my-assert + (mapcar (constantly 3) '(a b c d)) + (3 3 3 3)) + +(my-assert + (defmacro with-vars (vars &body forms) + `((lambda ,vars ,@forms) ,@(mapcar (constantly nil) vars))) + WITH-VARS) + +(my-assert + (multiple-value-bind (n h) + (macroexpand '(with-vars (a b) + (setq a 3 b (* a a)) + (list a b))) + (list n h)) + (((LAMBDA (A B) (SETQ A 3 B (* A A)) (LIST A B)) NIL NIL) t)) + +;;; every en co + +(my-assert + (every #'characterp "abc") + t) + +(my-assert + (some #'= '(1 2 3 4 5) '(5 4 3 2 1)) + t) + +(my-assert + (notevery #'< '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) + nil) + +(my-assert + (notany #'> '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) + t) + +;;; and + +(my-assert + (setq temp1 1 temp2 1 temp3 1) + 1 ) + +(my-assert + (and (incf temp1) (incf temp2) (incf temp3)) + 2 ) + +(my-assert + (and (eql 2 temp1) (eql 2 temp2) (eql 2 temp3)) + t) + +(my-assert + (decf temp3) + 1 ) + +(my-assert + (and (decf temp1) (decf temp2) (eq temp3 'nil) (decf temp3)) + NIL ) + +(my-assert + (and (eql temp1 temp2) (eql temp2 temp3)) + t) + +(my-assert + (and) + T ) + +;;; cond + +(my-assert + (defun select-options () + (cond ((= a 1) (setq a 2)) + ((= a 2) (setq a 3)) + ((and (= a 3) (floor a 2))) + (t (floor a 3)))) + SELECT-OPTIONS) + +(my-assert + (setq a 1) + 1) + +(my-assert + (select-options) + 2) + +(my-assert + a + 2) + +(my-assert + (select-options) + 3) + +(my-assert + a + 3) + +(my-assert + (select-options) + 1) + +(my-assert + (setq a 5) + 5) + +(my-assert + (multiple-value-bind (n h) + (select-options) + (list n h)) + (1 2)) + +;;; or + +(my-assert + (or) + NIL ) + +(my-assert + (setq temp0 nil temp1 10 temp2 20 temp3 30) + 30) + +(my-assert + (or temp0 temp1 (setq temp2 37)) + 10) + +(my-assert + temp2 + 20) + +(my-assert + (or (incf temp1) (incf temp2) (incf temp3)) + 11) + +(my-assert + temp1 + 11) + +(my-assert + temp2 + 20) + +(my-assert + temp3 + 30) + +(my-assert + (or (values) temp1) + 11) + +(my-assert + (or (values temp1 temp2) temp3) + 11) + +(my-assert + (multiple-value-bind (n h) + (or temp0 (values temp1 temp2)) + (list n h)) + (11 20)) + +(my-assert + (multiple-value-bind (n h) + (or (values temp0 temp1) (values temp2 temp3)) + (list n h)) + (20 30)) + +;;; when + +(my-assert + (when t 'hello) + HELLO) + +(my-assert + (unless t 'hello) + NIL) + +(my-assert + (when nil 'hello) + NIL) + +(my-assert + (unless nil 'hello) + HELLO) + +(my-assert + (when t) + NIL) + +(my-assert + (unless nil) + NIL) + +(my-assert + (when t (prin1 1) (prin1 2) (prin1 3)) + 3) + +(my-assert + (unless t (prin1 1) (prin1 2) (prin1 3)) + NIL) + +(my-assert + (when nil (prin1 1) (prin1 2) (prin1 3)) + NIL) + +(my-assert + (unless nil (prin1 1) (prin1 2) (prin1 3)) + 3) + +(my-assert + (let ((x 3)) + (list (when (oddp x) (incf x) (list x)) + (when (oddp x) (incf x) (list x)) + (unless (oddp x) (incf x) (list x)) + (unless (oddp x) (incf x) (list x)) + (if (oddp x) (incf x) (list x)) + (if (oddp x) (incf x) (list x)) + (if (not (oddp x)) (incf x) (list x)) + (if (not (oddp x)) (incf x) (list x)))) + ((4) NIL (5) NIL 6 (6) 7 (7))) + +;;; multiple-value-bind + +(my-assert + (multiple-value-bind (f r) + (floor 130 11) + (list f r)) + (11 9)) + +;;; multiple-value-call + +(my-assert + (multiple-value-call #'list 1 '/ (values 2 3) '/ (values) '/ (floor 2.5)) + (1 / 2 3 / / 2 0.5)) + +(my-assert + (+ (floor 5 3) (floor 19 4)) + 5) + +(my-assert + (multiple-value-call #'+ (floor 5 3) (floor 19 4)) + 10) + +;;; multiple-value-list + +(my-assert + (multiple-value-list (floor -3 4)) + (-1 1)) + +;;; multiple-value-prog1 + +(my-assert + (setq temp '(1 2 3)) + (1 2 3)) + +(my-assert + (multiple-value-bind (n h j) + (multiple-value-prog1 + (values-list temp) + (setq temp nil) + (values-list temp)) + (list n h j)) + (1 2 3)) + +;;; multiple-value-setq + +(my-assert + (multiple-value-setq (quotient remainder) (truncate 3.2 2)) + 1) + +(my-assert + quotient + 1) + +(my-assert + remainder + 1.2) + +(my-assert + (multiple-value-setq (a b c) (values 1 2)) + 1) + +(my-assert + a + 1) + +(my-assert + b + 2) + +(my-assert + c + NIL) + +(my-assert + (multiple-value-setq (a b) (values 4 5 6)) + 4) + +(my-assert + a + 4) + +(my-assert + b + 5) + +;;; values + +(my-assert + (values 1) + 1) + +(my-assert + (multiple-value-bind (n h) + (values 1 2) + (list n h)) + (1 2)) + +(my-assert + (multiple-value-bind (n h j) + (values 1 2 3) + (list n h j)) + (1 2 3)) + +(my-assert + (multiple-value-bind (n h j) + (values (values 1 2 3) 4 5) + (list n h j)) + (1 4 5)) + +(my-assert + (defun polar (x y) + (values (sqrt (+ (* x x) (* y y))) (atan y x))) + POLAR) + +(my-assert + (multiple-value-bind (r theta) (polar 3.0 4.0) + (vector r theta)) + #(5.0 0.9272952)) + +;;; values-list + +(my-assert + (values-list '(1)) + 1) + +(my-assert + (multiple-value-bind (n h) + (values-list '(1 2)) + (list n h)) + (1 2)) + +(my-assert + (multiple-value-bind (n h j) + (values-list '(1 2 3)) + (list n h j)) + (1 2 3)) + +;;; multiple-values-limit + +(my-assert + (>= MULTIPLE-VALUES-LIMIT 20) + T) + + +;;; nth-value + +(my-assert + (nth-value 0 (values 'a 'b)) + A) + +(my-assert + (nth-value 1 (values 'a 'b)) + B) + +(my-assert + (nth-value 2 (values 'a 'b)) + NIL) + +(my-assert + (multiple-value-bind (n h j) + (let* ((x 83927472397238947423879243432432432) + (y 32423489732) + (a (nth-value 1 (floor x y))) + (b (mod x y))) + (values a b (= a b))) + (list n h j)) + (3332987528 3332987528 t)) + +;;; prog + +(my-assert + (setq a 1) + 1) + +(my-assert + (prog ((a 2) (b a)) (return (if (= a b) '= '/=))) + /=) + +(my-assert + (prog* ((a 2) (b a)) (return (if (= a b) '= '/=))) + =) + +(my-assert + (prog () 'no-return-value) + NIL) + +;;; prog1 + +(my-assert + (setq temp 1) + 1) + +(my-assert + (prog1 temp (print temp) (incf temp) (print temp)) + 1) + +(my-assert + (prog1 temp (setq temp nil)) + 2) + +(my-assert + temp + NIL) + +(my-assert + (prog1 (values 1 2 3) 4) + 1 ) + +(my-assert + (setq temp (list 'a 'b 'c)) + (A B C)) + +(my-assert + (prog1 (car temp) (setf (car temp) 'alpha)) + A) + +(my-assert + temp + (ALPHA B C)) + +(my-assert + (multiple-value-bind (n h) + (flet ((swap-symbol-values (x y) + (setf (symbol-value x) + (prog1 (symbol-value y) + (setf (symbol-value y) (symbol-value x)))))) + (let ((*foo* 1) (*bar* 2)) + (declare (special *foo* *bar*)) + (swap-symbol-values '*foo* '*bar*) + (values *foo* *bar*))) + (list n h)) + (2 1)) + +(my-assert + (setq temp 1) + 1) + +(my-assert + (prog2 (incf temp) (incf temp) (incf temp)) + 3) + +(my-assert + temp + 4) + +(my-assert + (prog2 1 (values 2 3 4) 5) + 2) + +;;; progn + +(my-assert + (progn) + NIL) + +(my-assert + (progn 1 2 3) + 3) + +(my-assert + (multiple-value-bind (n h j) + (progn (values 1 2 3)) + (list n h j)) + (1 2 3)) + +(my-assert + (setq a 1) + 1) + +(my-assert + (if a + (progn (setq a nil) 'here) + (progn (setq a t) 'there)) + HERE) + +(my-assert + a + NIL) + +;;; define-modify-macro + +(my-assert + (define-modify-macro appendf (&rest args) + append "Append onto list") + APPENDF) + +(my-assert + (setq x '(a b c) y x) + (A B C)) + +(my-assert + (appendf x '(d e f) '(1 2 3)) + (A B C D E F 1 2 3)) + +(my-assert + x + (A B C D E F 1 2 3)) + +(my-assert + y + (A B C)) + +;;; defsetf + +(my-assert + (defun middleguy (x) (nth (truncate (1- (list-length x)) 2) x)) + MIDDLEGUY) + +(my-assert + (defun set-middleguy (x v) + (unless (null x) + (rplaca (nthcdr (truncate (1- (list-length x)) 2) x) v)) + v) + SET-MIDDLEGUY) + +(my-assert + (defsetf middleguy set-middleguy) + MIDDLEGUY) + +(my-assert + (setq a (list 'a 'b 'c 'd) + b (list 'x) + c (list 1 2 3 (list 4 5 6) 7 8 9)) + (1 2 3 (4 5 6) 7 8 9)) + +(my-assert + (setf (middleguy a) 3) + 3) + +(my-assert + (setf (middleguy b) 7) + 7) + +(my-assert + (setf (middleguy (middleguy c)) 'middleguy-symbol) + MIDDLEGUY-SYMBOL) + +(my-assert + a + (A 3 C D)) + +(my-assert + b + (7)) + +(my-assert + c + (1 2 3 (4 MIDDLEGUY-SYMBOL 6) 7 8 9)) + +(my-assert + (defsetf subseq (sequence start &optional end) (new-sequence) + `(progn (replace ,sequence ,new-sequence + :start1 ,start :end1 ,end) + ,new-sequence)) + SUBSEQ) + +(unintern '*XY*) + +(my-assert + (defvar *xy* (make-array '(10 10) :initial-element NIL)) + *XY*) + +(defun xy (&key ((:x x) 0) ((:y y) 0)) + (aref *xy* x y)) + +(defun set-xy (new-value &key ((:x x) 0) ((:y y) 0)) + (setf (aref *xy* x y) new-value)) + +(defsetf xy (&key ((:x x) 0) ((:y y) 0)) (store) + `(set-xy ,store :x ,x :y ,y)) + +(my-assert + (progn + (get-setf-expansion '(xy :x a :y b)) + t) + t) + +(my-assert + (xy :x 1) + NIL) + +(my-assert + (setf (xy :x 1) 1) + 1) + +(my-assert + (xy :x 1) + 1) + +(my-assert + (setf (xy :x 1 :y 2) 3) + 3) + +(my-assert + (setf (xy :y 5 :x 9) 14) + 14) + +(my-assert + (xy :y 0 :x 1) + 1) + +(my-assert + (xy :x 1 :y 2) + 3) + +;;; define-setf-expander + +(my-assert + (defun lastguy (x) (car (last x))) + LASTGUY) + +(my-assert + (define-setf-expander lastguy (x &environment env) + "Set the last element in a list to the given value." + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-expansion x env) + (let ((store (gensym))) + (values dummies + vals + `(,store) + `(progn (rplaca (last ,getter) ,store) ,store) + `(lastguy ,getter))))) + LASTGUY) + +(my-assert + (setq a (list 'a 'b 'c 'd) + b (list 'x) + c (list 1 2 3 (list 4 5 6))) + (1 2 3 (4 5 6))) + +(my-assert + (setf (lastguy a) 3) + 3) + +(my-assert + (setf (lastguy b) 7) + 7) + +(my-assert + (setf (lastguy (lastguy c)) 'lastguy-symbol) + LASTGUY-SYMBOL) + +(my-assert + a + (A B C 3)) + +(my-assert + b + (7)) + +(my-assert + c + (1 2 3 (4 5 LASTGUY-SYMBOL))) + +;;; setf + +(my-assert + (setq x (cons 'a 'b) y (list 1 2 3)) + (1 2 3) ) + +(my-assert + (setf (car x) 'x (cadr y) (car x) (cdr x) y) + (1 X 3) ) + +(my-assert + x + (X 1 X 3) ) + +(my-assert + y + (1 X 3) ) + +(my-assert + (setq x (cons 'a 'b) y (list 1 2 3)) + (1 2 3) ) + +(my-assert + (psetf (car x) 'x (cadr y) (car x) (cdr x) y) + NIL ) + +(my-assert + x + (X 1 A 3) ) + +(my-assert + y + (1 A 3) ) + +;;; shiftf + +(my-assert + (setq x (list 1 2 3) y 'trash) + TRASH) + +(my-assert + (shiftf y x (cdr x) '(hi there)) + TRASH) + +(my-assert + x + (2 3)) + +(my-assert + y + (1 HI THERE)) + +(my-assert + (setq x (list 'a 'b 'c)) + (A B C)) + +(my-assert + (shiftf (cadr x) 'z) + B) + +(my-assert + x + (A Z C)) + +(my-assert + (shiftf (cadr x) (cddr x) 'q) + Z) + +(my-assert + x + (A (C) . Q)) + +(my-assert + (setq n 0) + 0) + +(my-assert + (setq x (list 'a 'b 'c 'd)) + (A B C D)) + +(my-assert + (shiftf (nth (setq n (+ n 1)) x) 'z) + B) + +(my-assert + x + (A Z C D)) + +;;; rotatef + +(my-assert + (let ((n 0) + (x (list 'a 'b 'c 'd 'e 'f 'g))) + (rotatef (nth (incf n) x) + (nth (incf n) x) + (nth (incf n) x)) + x) + (A C D B E F G)) + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ansi-tests/section6.lisp b/src/ansi-tests/section6.lisp new file mode 100644 index 000000000..26c558d70 --- /dev/null +++ b/src/ansi-tests/section6.lisp @@ -0,0 +1,626 @@ +;;; 6.1.1.7 -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;; Collect values by using FOR constructs. +(my-assert + (loop for numlist in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + for a of-type integer = (first numlist) + and b of-type integer = (second numlist) + and c of-type float = (third numlist) + collect (list c b a)) + ((4.0 2 1) (8.3 6 5) (10.4 9 8))) + + + +;; Destructuring simplifies the process. +(my-assert + (loop for (a b c) of-type (integer integer float) in + '((1 2 4.0) (5 6 8.3) (8 9 10.4)) + collect (list c b a)) + ((4.0 2 1) (8.3 6 5) (10.4 9 8))) + + +;; If all the types are the same, this way is even simpler. +(my-assert + (loop for (a b c) of-type float in + '((1.0 2.0 4.0) (5.0 6.0 8.3) (8.0 9.0 10.4)) + collect (list c b a)) + ((4.0 2.0 1.0) (8.3 6.0 5.0) (10.4 9.0 8.0))) + +;; Initialize and declare variables in parallel by using the AND construct. + +(my-assert + (loop for (a nil b) = '(1 2 3) + do (return (list a b))) + (1 3)) + +(my-assert + (loop for (x . y) = '(1 . 2) + do (return y)) + 2) + + +(my-assert + (loop for ((a . b) (c . d)) of-type ((float . float) (integer . integer)) in + '(((1.2 . 2.4) (3 . 4)) ((3.4 . 4.6) (5 . 6))) + collect (list a b c d)) + ((1.2 2.4 3 4) (3.4 4.6 5 6))) + +;;; 6.1.2.1.1 + + +(my-assert + (let ((xo 1)) (loop for i from xo by (incf xo) to 10 collect i)) + (1 3 5 7 9)) + + +;;; 6.1.2.1.2.1 + +(my-assert + (loop for (item . x) of-type (t . fixnum) in '((A . 1) (B . 2) (C . 3)) + unless (eq item 'B) sum x) + 4) + +;;; 6.1.2.1.3.1 + +;; Collect successive tails of a list. +(my-assert + (loop for sublist on '(a b c d) + collect sublist) + ((A B C D) (B C D) (C D) (D))) + +;;; 6.1.2.1.4.1 + +;; Collect some numbers. +(my-assert + (loop for item = 1 then (+ item 10) + for iteration from 1 to 5 + collect item) + (1 11 21 31 41)) + +;;;; 6.1.2.2 + +(my-assert + (loop with a = 1 + with b = (+ a 2) + with c = (+ b 3) + return (list a b c)) + (1 3 6)) + +(my-assert + (loop with a = 1 + and b = 2 + and c = 3 + return (list a b c)) + (1 2 3)) + +;;; 6.1.2.2.1 + +;; These bindings occur in sequence. +(my-assert + (loop with a = 1 + with b = (+ a 2) + with c = (+ b 3) + return (list a b c)) + (1 3 6)) + +;; These bindings occur in parallel. +(my-assert + (setq a 5 b 10) + 10) + + +(my-assert + (loop with a = 1 + and b = (+ a 2) + and c = (+ b 3) + return (list a b c)) + (1 7 13)) + +;; This example shows a shorthand way to declare local variables +;; that are of different types. +(my-assert + (loop with (a b c) of-type (float integer float) + return (format nil "~A ~A ~A" a b c)) + "0.0 0 0.0") + +;; This example shows a shorthand way to declare local variables +;; that are the same type. +(my-assert + (loop with (a b c) of-type float + return (format nil "~A ~A ~A" a b c)) + "0.0 0.0 0.0") + +;;; 6.1.3 + +;; Collect every name and the kids in one list by using +;; COLLECT and APPEND. +(my-assert + (loop for name in '(fred sue alice joe june) + for kids in '((bob ken) () () (kris sunshine) ()) + collect name + append kids) + (FRED BOB KEN SUE ALICE JOE KRIS SUNSHINE JUNE)) + +;;; 6.1.3.1 + +;; Collect all the symbols in a list. +(my-assert + (loop for i in '(bird 3 4 turtle (1 . 4) horse cat) + when (symbolp i) collect i) + (BIRD TURTLE HORSE CAT)) + +;; Collect and return odd numbers. +(my-assert + (loop for i from 1 to 10 + if (oddp i) collect i) + (1 3 5 7 9)) + +;; Collect items into local variable, but don't return them. +(my-assert + (loop for i in '(a b c d) by #'cddr + collect i into my-list + finally my-list) ;;; hmm + nil ) + +;;; 6.1.3.2 + +;; Use APPEND to concatenate some sublists. +(my-assert + (loop for x in '((a) (b) ((c))) + append x) + (A B (C))) + +;; NCONC some sublists together. Note that only lists made by the +;; call to LIST are modified. +(my-assert + (loop for i upfrom 0 + as x in '(a b (c)) + nconc (if (evenp i) (list x) nil)) + (A (C))) + +;;; 6.1.3.3 + +(my-assert + (loop for i in '(a b nil c nil d e) + count i) + 5) + +;;; 6.1.3.4 + +(my-assert + (loop for i in '(2 1 5 3 4) + maximize i) + 5) + +(my-assert + (loop for i in '(2 1 5 3 4) + minimize i) + 1) + +;; In this example, FIXNUM applies to the internal variable that holds +;; the maximum value. +(my-assert + (setq series '(1.2 4.3 5.7)) + (1.2 4.3 5.7)) + +(my-assert + (loop for v in series + maximize (round v) of-type fixnum) + 6) + +;; In this example, FIXNUM applies to the variable RESULT. +(my-assert + (loop for v of-type float in series + minimize (round v) into result of-type fixnum + finally (return result)) + 1) + +;;; 6.1.3.5 + +(my-assert + (loop for i of-type fixnum in '(1 2 3 4 5) + sum i) + 15) + +(my-assert + (setq series '(1.2 4.3 5.7)) + (1.2 4.3 5.7)) + +(my-assert + (loop for v in series + sum (* 2.0 v)) + 22.4) + +;;; 6.1.4.2 + +;; Make sure I is always less than 11 (two ways). +;; The FOR construct terminates these loops. +(my-assert + (loop for i from 0 to 10 + always (< i 11)) + T) + +(my-assert + (loop for i from 0 to 10 + never (> i 11)) + T) + +;; If I exceeds 10 return I; otherwise, return NIL. +;; The THEREIS construct terminates this loop. +(my-assert + (loop for i from 0 + thereis (when (> i 10) i) ) + 11) + +;;; The FINALLY clause is not evaluated in these examples. +(my-assert + (loop for i from 0 to 10 + always (< i 9) + finally (format nil "you won't see this")) + NIL) + +(my-assert + (loop never t + finally (format nil "you won't see this")) + NIL) + +(my-assert + (loop thereis "Here is my value" + finally (format nil "you won't see this")) + "Here is my value") + +;;; 6.1.4.3 + +;; Collect the length and the items of STACK. +(my-assert + (let ((stack '(a b c d e f))) + (loop for item = (length stack) then (pop stack) + collect item + while stack)) + (6 A B C D E F)) + +;; Use WHILE to terminate a loop that otherwise wouldn't terminate. +;; Note that WHILE occurs after the WHEN. +(my-assert + (loop for i fixnum from 3 + when (oddp i) collect i + while (< i 5)) + (3 5)) + +;;; 6.1.6.1 + +;; Signal an exceptional condition. +(my-assert + (loop for item in '(1 2 3 a 4 5) + when (not (numberp item)) + return (cerror "enter new value" "non-numeric value: ~s" item)) + ERROR) + +;; The previous example is equivalent to the following one. +(my-assert + (loop for item in '(1 2 3 a 4 5) + when (not (numberp item)) + do (return + (cerror "Enter new value" "non-numeric value: ~s" item))) + ERROR) + +;; This example parses a simple printed string representation from +;; BUFFER (which is itself a string) and returns the index of the +;; closing double-quote character. +(my-assert + (let ((buffer "\"a\" \"b\"")) + (loop initially (unless (char= (char buffer 0) #\") + (loop-finish)) + for i of-type fixnum from 1 below (length (the string buffer)) + when (char= (char buffer i) #\") + return i)) + 2) + +;; The collected value is returned. +(my-assert + (loop for i from 1 to 10 + when (> i 5) + collect i + finally (prin1 'got-here)) + (6 7 8 9 10) ) + +;; Return both the count of collected numbers and the numbers. + +(my-assert + (multiple-value-bind (a b) + (loop for i from 1 to 10 + when (> i 5) + collect i into number-list + and count i into number-count + finally (return (values number-count number-list))) + (list a b)) + (5 (6 7 8 9 10))) + +;;; 6.1.7.1.1 + +;; Just name and return. +(my-assert + (loop named max + for i from 1 to 10 + do (print i) + do (return-from max 'done)) + DONE) + + + +;;; 6.1.8 + +(my-assert + (let ((i 0)) ; no loop keywords are used + (loop (incf i) (if (= i 3) (return i)))) + 3) + +(my-assert + (let ((i 0)(j 0)) + (tagbody + (loop (incf j 3) (incf i) (if (= i 3) (go exit))) + exit) + j) + 9) + +(my-assert + (loop for x from 1 to 10 + for y = nil then x + collect (list x y)) + ((1 NIL) (2 2) (3 3) (4 4) (5 5) (6 6) (7 7) (8 8) (9 9) (10 10))) + +(my-assert + (loop for x from 1 to 10 + and y = nil then x + collect (list x y)) + ((1 NIL) (2 1) (3 2) (4 3) (5 4) (6 5) (7 6) (8 7) (9 8) (10 9))) + +;;; 6.1.8.1 + +;; Group conditional clauses. + +(my-assert + (multiple-value-bind (a b) + (loop for i in '(1 324 2345 323 2 4 235 252) + when (oddp i) + do (print i) + and collect i into odd-numbers + and do (terpri) + else ; I is even. + collect i into even-numbers + finally + (return (values odd-numbers even-numbers))) + (list a b)) + ((1 2345 323 235) (324 2 4 252))) + +;; Collect numbers larger than 3. +(my-assert + (loop for i in '(1 2 3 4 5 6) + when (and (> i 3) i) + collect it) ; IT refers to (and (> i 3) i). + (4 5 6)) + +;; Find a number in a list. +(my-assert + (loop for i in '(1 2 3 4 5 6) + when (and (> i 3) i) + return it) + 4) + +;; The above example is similar to the following one. +(my-assert + (loop for i in '(1 2 3 4 5 6) + thereis (and (> i 3) i)) + 4) + + +;; Nest conditional clauses. +(my-assert + (multiple-value-bind (a b c) + (let ((list '(0 3.0 apple 4 5 9.8 orange banana))) + (loop for i in list + when (numberp i) + when (floatp i) + collect i into float-numbers + else ; Not (floatp i) + collect i into other-numbers + else ; Not (numberp i) + when (symbolp i) + collect i into symbol-list + else ; Not (symbolp i) + do (error "found a funny value in list ~S, value ~S~%" list i) + finally (return (values float-numbers other-numbers symbol-list)))) + (list a b c)) + ((3.0 9.8) (0 4 5) (APPLE ORANGE BANANA))) + +;;; do + +(my-assert + (do ((temp-one 1 (1+ temp-one)) + (temp-two 0 (1- temp-two))) + ((> (- temp-one temp-two) 5) temp-one)) + 4) + +(my-assert + (do ((temp-one 1 (1+ temp-one)) + (temp-two 0 (1+ temp-one))) + ((= 3 temp-two) temp-one)) + 3) + +(my-assert + (do* ((temp-one 1 (1+ temp-one)) + (temp-two 0 (1+ temp-one))) + ((= 3 temp-two) temp-one)) + 2 ) + +(my-assert + (setq a-vector (vector 1 nil 3 nil)) + #(1 nil 3 nil)) + +(my-assert + (do ((i 0 (+ i 1)) ;Sets every null element of a-vector to zero. + (n (array-dimension a-vector 0))) + ((= i n)) + (when (null (aref a-vector i)) + (setf (aref a-vector i) 0))) + NIL) + +(my-assert + a-vector + #(1 0 3 0)) + +;;; dotimes + +(my-assert + (dotimes (temp-one 10 temp-one)) + 10) + +(my-assert + (setq temp-two 0) + 0) + +(my-assert + (dotimes (temp-one 10 t) (incf temp-two)) + T) + +(my-assert + temp-two + 10) + +;;; True if the specified subsequence of the string is a +;;; palindrome (reads the same forwards and backwards). +(my-assert + (defun palindromep (string &optional + (start 0) + (end (length string))) + (dotimes (k (floor (- end start) 2) t) + (unless (char-equal (char string (+ start k)) + (char string (- end k 1))) + (return nil)))) + PALINDROMEP) + +(my-assert + (palindromep "Able was I ere I saw Elba") + T) + +(my-assert + (palindromep "A man, a plan, a canal--Panama!") + NIL) + +(my-assert + (remove-if-not #'alpha-char-p ;Remove punctuation. + "A man, a plan, a canal--Panama!") + "AmanaplanacanalPanama") + +(my-assert + (palindromep + (remove-if-not #'alpha-char-p + "A man, a plan, a canal--Panama!")) + T) + +(my-assert + (palindromep + (remove-if-not + #'alpha-char-p + "Unremarkable was I ere I saw Elba Kramer, nu?")) + T) + +(my-assert + (palindromep + (remove-if-not + #'alpha-char-p + "A man, a plan, a cat, a ham, a yak, + a yam, a hat, a canal--Panama!")) + T) + + +;;; dolist + +(my-assert + (setq temp-two '()) + NIL) + +(my-assert + (dolist (temp-one '(1 2 3 4) temp-two) (push temp-one temp-two)) + (4 3 2 1)) + +(my-assert + (setq temp-two 0) + 0) + +(my-assert + (dolist (temp-one '(1 2 3 4)) (incf temp-two)) + NIL) + +(my-assert + temp-two + 4) + +;;; loop-finish + +;; Terminate the loop, but return the accumulated count. +(my-assert + (loop for i in '(1 2 3 stop-here 4 5 6) + when (symbolp i) do (loop-finish) + count i) + 3) + +;; The preceding loop is equivalent to: +(my-assert + (loop for i in '(1 2 3 stop-here 4 5 6) + until (symbolp i) + count i) + 3) + +;; While LOOP-FINISH can be used can be used in a variety of +;; situations it is really most needed in a situation where a need +;; to exit is detected at other than the loop's `top level' +;; (where UNTIL or WHEN often work just as well), or where some +;; computation must occur between the point where a need to exit is +;; detected and the point where the exit actually occurs. For example: +(my-assert + (defun tokenize-sentence (string) + (macrolet ((add-word (wvar svar) + `(when ,wvar + (push (coerce (nreverse ,wvar) 'string) ,svar) + (setq ,wvar nil)))) + (loop with word = '() and sentence = '() and endpos = nil + for i below (length string) + do (let ((char (aref string i))) + (case char + (#\Space (add-word word sentence)) + (#\. (setq endpos (1+ i)) (loop-finish)) + (otherwise (push char word)))) + finally (add-word word sentence) + (return (values (nreverse sentence) endpos))))) + TOKENIZE-SENTENCE) + +(my-assert + (multiple-value-bind (a b) + (tokenize-sentence + "this is a sentence. this is another sentence.") + (list a b)) + (("this" "is" "a" "sentence") 19)) + +(my-assert + (multiple-value-bind (a b) + (tokenize-sentence "this is a sentence") + (list a b)) + (("this" "is" "a" "sentence") NIL)) + + + + + + + + + + + + + + diff --git a/src/ansi-tests/section7.lisp b/src/ansi-tests/section7.lisp new file mode 100644 index 000000000..7ba601397 --- /dev/null +++ b/src/ansi-tests/section7.lisp @@ -0,0 +1,48 @@ +;;; section 7: objects -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; function-keywords +(my-assert + (progn + (defmethod gf1 ((a integer) &optional (b 2) + &key (c 3) ((:dee d) 4) e ((eff f))) + (list a b c d e f)) + t) + T) + +(my-assert + (eq (find-method #'gf1 '() (list (find-class 'integer))) 'nil) + nil) ; XXX + +(my-assert + (multiple-value-list + (function-keywords (find-method #'gf1 '() + (list (find-class 'integer))))) + ((:C :DEE :E EFF) nil)) + +(my-assert + (eq (defmethod gf2 ((a integer)) + (list a b c d e f)) 'nil) + nil) ; XXX + +(my-assert + (multiple-value-list + (function-keywords (find-method #'gf2 '() (list (find-class 'integer))))) + (() nil)) + +(my-assert + (progn + (defmethod gf3 ((a integer) &key b c d &allow-other-keys) + (list a b c d e f)) + t) + t) + +(my-assert + (multiple-value-list + (function-keywords (find-method #'gf3 '() (list (find-class 'integer))))) + ((:B :C :D) t)) + +;;; if only i knew more about clos + diff --git a/src/ansi-tests/section8.lisp b/src/ansi-tests/section8.lisp new file mode 100644 index 000000000..887f82105 --- /dev/null +++ b/src/ansi-tests/section8.lisp @@ -0,0 +1,200 @@ +;;; section 8 structures -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + +;;; +;;; Example 1 +;;; define town structure type +;;; area, watertowers, firetrucks, population, elevation are its components +;;; +(my-assert + (defstruct town + area + watertowers + (firetrucks 1 :type fixnum) ;an initialized slot + population + (elevation 5128 :read-only t)) ;a slot that can't be changed + TOWN) + + ;create a town instance +(my-assert + (progn + (setq town1 (make-town :area 0 :watertowers 0)) + t) + t ) + + ;town's predicate recognizes the new instance +(my-assert + (town-p town1) + t) + + ;new town's area is as specified by make-town +(my-assert + (town-area town1) + 0) + + ;new town's elevation has initial value +(my-assert + (town-elevation town1) + 5128) + + ;setf recognizes reader function +(my-assert + (setf (town-population town1) 99) + 99) + +(my-assert + (town-population town1) + 99) + + ;copier function makes a copy of town1 +(my-assert + (progn + (setq town2 (copy-town town1)) + t) + t) + +(my-assert + (= (town-population town1) (town-population town2)) + t) + + ;since elevation is a read-only slot, its value can be set only + ;when the structure is created +(my-assert + (progn + (setq town3 (make-town :area 0 :watertowers 3 :elevation 1200)) + t) + t) + +;;; +;;; Example 2 +;;; define clown structure type +;;; this structure uses a nonstandard prefix +;;; +(my-assert + (defstruct (clown (:conc-name bozo-)) + (nose-color 'red) + frizzy-hair-p polkadots) + CLOWN) + +(my-assert + (progn + (setq funny-clown (make-clown)) + t) + t) + + ;use non-default reader name +(my-assert + (bozo-nose-color funny-clown) + RED ) + +(my-assert + (defstruct (klown (:constructor make-up-klown) ;similar def using other + (:copier clone-klown) ;customizing keywords + (:predicate is-a-bozo-p)) + nose-color frizzy-hair-p polkadots) + klown) + + ;custom constructor now exists +(my-assert + (fboundp 'make-up-klown) + t) + +;;; +;;; Example 3 +;;; define a vehicle structure type +;;; then define a truck structure type that includes +;;; the vehicle structure +;;; +(my-assert + (defstruct vehicle name year (diesel t :read-only t)) + VEHICLE) + +(my-assert + (defstruct (truck (:include vehicle (year 79))) + load-limit + (axles 6)) + TRUCK) + +(my-assert + (progn + (setq x (make-truck :name 'mac :diesel t :load-limit 17)) + t) + t) + + ;vehicle readers work on trucks +(my-assert + (vehicle-name x) + MAC) + + ;default taken from :include clause +(my-assert + (vehicle-year x) + 79 ) + +(my-assert + (defstruct (pickup (:include truck)) ;pickup type includes truck + camper long-bed four-wheel-drive) + PICKUP) + +(my-assert + (progn + (setq x (make-pickup :name 'king :long-bed t)) + t) + t) + + ;:include default inherited +(my-assert + (pickup-year x) + 79) + +;;; +;;; Example 4 +;;; use of BOA constructors +;;; +(my-assert + (defstruct (dfs-boa ;BOA constructors + (:constructor make-dfs-boa (a b c)) + (:constructor create-dfs-boa + (a &optional b (c 'cc) &rest d &aux e (f 'ff)))) + a b c d e f) + DFS-BOA) + + ;a, b, and c set by position, and the rest are uninitialized +(my-assert + (progn + (setq x (make-dfs-boa 1 2 3)) + t) + t) + +(my-assert + (dfs-boa-a x) + 1) + + ;a and b set, c and f defaulted +(my-assert + (progn + (setq x (create-dfs-boa 1 2)) + t) + t) + +(my-assert + (dfs-boa-b x) + 2) + +(my-assert + (eq (dfs-boa-c x) 'cc) + t) + + ;a, b, and c set, and the rest are collected into d +(my-assert + (progn + (setq x (create-dfs-boa 1 2 3 4 5 6)) + t) + t) + +(my-assert + (dfs-boa-d x) + (4 5 6)) + diff --git a/src/ansi-tests/section9.lisp b/src/ansi-tests/section9.lisp new file mode 100644 index 000000000..25801d1d8 --- /dev/null +++ b/src/ansi-tests/section9.lisp @@ -0,0 +1,127 @@ +;;; section 9: conditions -*- mode: lisp -*- +(in-package :cl-user) + +(proclaim '(special log)) + + +(my-assert + (subtypep 'arithmetic-error 'condition) + t) + +(my-assert + (subtypep 'floating-point-overflow 'condition) + t) + +(my-assert + (subtypep 'simple-type-error 'condition) + t) + +(my-assert + (subtypep 'cell-error 'condition) + t) + +(my-assert + (subtypep 'floating-point-underflow 'condition) + t) + +(my-assert + (subtypep 'simple-warning 'condition) + t) + +(my-assert + (subtypep 'condition 'condition) + t) + +(my-assert + (subtypep 'package-error 'condition) + t) + +(my-assert + (subtypep 'storage-condition 'condition) + t) + +(my-assert + (subtypep 'control-error 'condition) + t) + +(my-assert + (subtypep 'parse-error 'condition) + t) + +(my-assert + (subtypep 'stream-error 'condition) + t) + +(my-assert + (subtypep 'division-by-zero 'condition) + t) + +(my-assert + (subtypep 'print-not-readable 'condition) + t) + +(my-assert + (subtypep 'style-warning 'condition) + t) + +(my-assert + (subtypep 'end-of-file 'condition) + t) + +(my-assert + (subtypep 'program-error 'condition) + t) + +(my-assert + (subtypep 'type-error 'condition) + t) + +(my-assert + (subtypep 'error 'condition) + t) + +(my-assert + (subtypep 'reader-error 'condition) + t) + +(my-assert + (subtypep 'unbound-slot 'condition) + t) + +(my-assert + (subtypep 'file-error 'condition) + t) + +(my-assert + (subtypep 'serious-condition 'condition) + t) + +(my-assert + (subtypep 'unbound-variable 'condition) + t) + +(my-assert + (subtypep 'floating-point-inexact 'condition) + t) + +(my-assert + (subtypep 'simple-condition 'condition) + t) + +(my-assert + (subtypep 'undefined-function 'condition) + t) + +(my-assert + (subtypep 'floating-point-invalid-operation 'condition) + t) + +(my-assert + (subtypep 'simple-error 'condition) + t) + +(my-assert + (subtypep 'warning 'condition) + t) + + diff --git a/src/ansi-tests/setf.lisp b/src/ansi-tests/setf.lisp new file mode 100644 index 000000000..2ec43a0b2 --- /dev/null +++ b/src/ansi-tests/setf.lisp @@ -0,0 +1,528 @@ +;;; based on v1.4 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (setf li1 '(a (b) ((c) (d)) ) vec1 '#(0 1 2 3)) + #(0 1 2 3)) + +(my-assert + (setf pa 'old) + old) + +(my-assert + (psetf pa 'new pao pa) + nil) + +(my-assert + pa + new) + +(my-assert + pao + old) + +(my-assert + (setf (nth 1 li1) (quote uu)) + uu) + +(my-assert + (eval (quote li1)) + (a uu ((c) (d)))) + +(my-assert + (setf (elt li1 1) (quote oo)) + oo) + +(my-assert + (setf (elt vec1 1) (quote oo)) + oo) + +(my-assert + (eval (quote li1)) + (a oo ((c) (d)))) + +(my-assert + (eval (quote vec1)) + #(0 oo 2 3)) + +(my-assert + (setf (rest li1) (quote ((ww)))) + ((ww))) + +(my-assert + (eval (quote li1)) + (a (ww))) + +(my-assert + (setf (first li1) (quote aa)) + aa) + +(my-assert + (first li1) + aa) + +(my-assert + (setf (second li1) (quote bb)) + bb) + +(my-assert + (eval (quote li1)) + (aa bb)) + +(my-assert + (setf (third li1) (quote bb)) + type-error) + +(my-assert + (eval (quote li1)) + (aa bb)) + + +(my-assert + (setf (rest li1) (quote (2 3 4 5 6 7 8 9 10))) + (2 3 4 5 6 7 8 9 10)) + +(my-assert + (setf (second li1) 22) + 22) + +(my-assert + (eval (quote li1)) + (aa 22 3 4 5 6 7 8 9 10)) + +(my-assert + (setf (third li1) (quote 33)) + 33) + +(my-assert + (setf (fourth li1) (quote 44)) + 44) + +(my-assert + (setf (fifth li1) (quote 55)) + 55) + +(my-assert + (setf (sixth li1) (quote 66)) + 66) + +(my-assert + (setf (seventh li1) (quote 77)) + 77) + +(my-assert + (setf (eighth li1) (quote 88)) + 88) + +(my-assert + (setf (ninth li1) (quote 99)) + 99) + +(my-assert + (setf (tenth li1) (quote 1010)) + 1010) + +(my-assert + (eval (quote li1)) + (aa 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (first li1) (quote (((a))))) + (((a)))) + +(my-assert + (setf (caaar li1) (quote uu)) + uu) + +(my-assert + (caaar li1) + uu) + +(my-assert + (car li1) + ((uu))) + +(my-assert + (setf (caar li1) (quote oo)) + oo) + +(my-assert + (eval (quote li1)) + ((oo) 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (car li1) (quote ii)) + ii) + +(my-assert + (eval (quote li1)) + (ii 22 33 44 55 66 77 88 99 1010)) + +(my-assert + (setf (cdddr li1) (quote pp)) + pp) + +(my-assert + (eval (quote li1)) + (ii 22 33 . pp)) + +(my-assert + (setf (caddr li1) (quote 333)) + 333) + +(my-assert + (eval (quote li1)) + (ii 22 333 . pp)) + +(my-assert + (setf (svref vec1 2) (quote kk)) + kk) + +(my-assert + (eval (quote vec1)) + #(0 oo kk 3)) + +(my-assert + (setf (get (quote a) (quote b)) (quote uu)) + uu) + +(my-assert + (get (quote a) (quote b)) + uu) + +(my-assert + (setf (getf (cadr (setq xx (quote (aaa (i1 v1 i2 v2))))) (quote i2)) + + (quote v222)) + v222) + +(my-assert + (eval (quote xx)) + (aaa (i1 v1 i2 v222))) + +(my-assert + (getf (cadr xx) (quote i2)) + v222) + +(my-assert + (getf (cadr xx) (quote i1)) + v1) + +(my-assert + (setf (documentation (quote beispiel) (quote typ1)) "doc 1") + "doc 1") + +(my-assert + (setf (documentation (quote beispiel) (quote typ2)) "doc 2") + "doc 2") + +(my-assert + (documentation (quote beispiel) (quote typ2)) + #+xcl (typ2 . "doc 2") + #-xcl "doc 2") + +(my-assert + (setf (documentation (quote beispiel) (quote typ2)) "doc 3") + "doc 3") + +(my-assert + (documentation (quote beispiel) (quote typ2)) + #+xcl (typ2 . "doc 3") + #-xcl "doc 3") + +(my-assert + (symbol-plist 'beispiel) + #+xcl (documentation ((typ2 . "doc 3") (typ1 . "doc 1"))) + #+clisp (system::documentation-strings (typ2 "doc 3" typ1 "doc 1")) + #+allegro (excl::%documentation ((typ2 . "doc 3") (typ1 . "doc 1"))) + #+(or cmu ecls) nil + #-(or xcl clisp allegro cmu ecls) unknown) + +(my-assert + (setf (symbol-value (quote xx)) (quote voelligneu)) + voelligneu) + +(my-assert + (eval (quote xx)) + voelligneu) + +(my-assert + (progn + (setf (symbol-function (quote ff)) + (coerce (quote (lambda (x) (print x) (quote hello))) (quote function))) + nil) + nil) + +(my-assert + (ff 5) + hello) + +(my-assert + (defun xx nil 'a) + xx) + +(my-assert + (progn (setf (symbol-function 'xx1) (symbol-function 'xx)) nil) + nil) + +(my-assert + (xx1) + a) + +(my-assert + (setq l '(a 1 c d)) + (a 1 c d)) + +(my-assert + (setf (the integer (cadr l)) 100) + 100) + +(my-assert + l + (a 100 c d)) + +(my-assert + (progn (setf a (make-hash-table)) t) + t) + +(my-assert + (setf (gethash 'color a) 'brown) + brown) + +(my-assert + (gethash 'color a) + brown) + +(my-assert + (defstruct schiff masse) + schiff) + +(my-assert + (progn (setf s1 (make-schiff)) nil) + nil) + +(my-assert + (setf (schiff-masse s1) 500) + 500) + +(my-assert + (schiff-masse s1) + 500) + +(my-assert + (defmacro setf-test (v) `(svref ,v 3)) + setf-test) + +(my-assert + (progn (setf (macro-function 'setf-test1) (macro-function 'setf-test)) nil) + nil) + +(my-assert + (setf (setf-test vec1) 'oho) + oho) + +(my-assert + (eval 'vec1) + #(0 oo kk oho)) + +(my-assert + (setf (setf-test1 vec1) 'hihi) + hihi) + +(my-assert + (eval 'vec1) + #(0 oo kk hihi)) + +;; (setf (displace ?? (svref vec1 3)) "aha") +;; aha + +;; (eval 'vec1) +;; #(0 oo kk aha) + +(my-assert + (progn (setf a (make-array '(4 3))) nil) + nil) + +(my-assert + (aref a 2 2) + #+(or xcl cmu) 0 + #+(or clisp akcl allegro ecls) nil + #-(or xcl clisp akcl allegro cmu ecls) unknown) + +(my-assert + (setf (apply #'aref a '(2 2)) 'xxxx) + xxxx) + +(my-assert + (aref a 2 2) + xxxx) + +(my-assert + (setf (aref '#(a b c) 1) (quote ii)) + ii) + +(my-assert + (setf b #*101010) + #*101010) + +(my-assert + (bit b 2) + 1) + +(my-assert + (setf (bit b 2) 0) + 0) + +(my-assert + (bit b 2) + 0) + +(my-assert + (setf (sbit b 2) 1) + 1) + +(my-assert + (sbit b 2) + 1) + +(my-assert + (progn (setf a (make-array 5 :fill-pointer t)) t) + t) + +(my-assert + (fill-pointer a) + 5) + +(my-assert + (setf (fill-pointer a) 3) + 3) + +(my-assert + (fill-pointer a) + 3) + +(my-assert + (let ((str (copy-seq "hose"))) + str) + "hose") + +(my-assert + (let ((str (copy-seq "hose"))) + (setf (char str 0) #\d)) + #\d) + +(my-assert + (let ((str (copy-seq "hose"))) + (setf (char str 0) #\d) + str) + "dose") + +(my-assert + (let ((str (copy-seq "hose"))) + (setf (char str 0) #\d) + (setf str "aaaxxxccc")) + "aaaxxxccc") + +(my-assert + (let ((str (copy-seq "hose"))) + (setf (char str 0) #\d) + (setf str (copy-seq "aaaxxxccc")) + (setf (subseq str 3 6) "bbb")) + "bbb") + +(my-assert + (let ((str (copy-seq "hose"))) + (setf (char str 0) #\d) + (setf str (copy-seq "aaaxxxccc")) + (setf (subseq str 3 6) "bbb") + str) + "aaabbbccc") + +(my-assert + (setq x (list 'a 'b 'c)) + (a b c)) + +(my-assert + (shiftf (cadr x) 'z) + b) + +(my-assert + x + (a z c)) + +(my-assert + (shiftf (cadr x) (cddr x) 'q) + z) + +(my-assert + x + (a (c) . q)) + +(my-assert + (progn + (defun ad (x) (values (car x) (cdr x))) + (defsetf ad (x) (a b) `(setf (values (car ,x) (cdr ,x)) (values ,a ,b))) + (setq x (cons 1 2) y 3 z 4 w 5 v 6 u 7)) + 7) + +(my-assert + (rotatef (ad x) (values y z) (values w v u)) + nil) + +(my-assert + x + (3 . 4)) + +(my-assert + (list y z w v u) + (5 6 1 2 nil)) + +(my-assert + (multiple-value-list + (shiftf (ad x) + (values y z w) + (values v u) + (floor 89 10))) + (3 4) + "(ad x) -> 3 and 4) + (y -> 5 z -> 6 w -> 1) + (v -> 2 u-> nil) + (floor 89 10) -> 8 and 9 + +so after shifting we expect: +x -> (5 . 6) +(y -> 2 z-> nil w -> nil) +(v -> 8 u -> 9) + +and we return 3 and 4") + +(my-assert + x + (5 . 6) + "check the shiftf result") + +(my-assert + (list y z w v u) + (2 nil nil 8 9) + "check the shiftf result") + +(my-assert + (progn (defsetf subseq (sequence start &optional end) (new-sequence) + `(progn (replace ,sequence ,new-sequence + :start1 ,start :end1 ,end) + ,new-sequence)) t) + t) + +(my-assert + (let (s) + (setf s (copy-seq "asdfg") + (subseq s 1 3) "xy")) + "xy") + +(my-assert + (let (s) + (setf s (copy-seq "asdfg") + (subseq s 1 3) "xy") + s) + "axyfg") + diff --git a/src/ansi-tests/steele7.lisp b/src/ansi-tests/steele7.lisp new file mode 100644 index 000000000..2e6e24638 --- /dev/null +++ b/src/ansi-tests/steele7.lisp @@ -0,0 +1,560 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) +;;; +;;; testfile nach steele-beispielen +;;; + +;; 7.3 + + +(my-assert + (let ((f '+)) + (apply f '(1 2))) + 3) + +(my-assert + (let ((f #'-)) + (apply f '(1 2))) + -1) + +(my-assert + (apply #'max 3 5 '(2 7 3)) + 7) + +(my-assert + (apply 'cons '((+ 2 3) 4)) + ((+ 2 3) . 4)) + + +(my-assert + (apply #'+ '()) + 0) + +(my-assert + (apply #'(lambda (&key a b)(list a b)) '(:b 3)) + (nil 3)) + + +(my-assert + (funcall '+ 2 3) + 5) + +(my-assert + (let ((c (symbol-function '+))) + (funcall c 1 2 3 4)) + 10) + + +;;abschnitt 7.4 + +;; progn +(my-assert + (progn 1 2 3) + 3) + +(my-assert + (progn (+ 2 1) 2) + 2) + +(my-assert + (progn 1 2 (values 2 3)) + 2) + +(my-assert + (progn) + nil) + + +;; prog1 +(my-assert + (prog1 1 2 3) + 1) + +(my-assert + (prog1 3 (+ 1 2) 2) + 3) + +(my-assert + (prog1 (values 2 3) 1 2 ) + 2) + +(my-assert + (let ((x '(a b c))) + (prog1 (car x)(rplaca x 'foo))) + a) + +;; prog2 + +(my-assert + (prog2 1 2 3) + 2) + +(my-assert + (prog2 (+ 1 2) 2 3) + 2) + +(my-assert + (prog2 1 (values 2 3) 4) + 2) + +;; 7.5 + +;; let +(setf a 0) + +(my-assert + (let ((a 1)(b 2) c) + (declare (integer a b)) + (list a b c)) + (1 2 nil)) + + +(my-assert + (let ((a 1) + (b a)) + (declare (integer a b)) + (list a b)) + (1 0)) + +(my-assert + (let (x239) + (declare (special x239)) + (symbol-value 'x239)) + nil) + +;; let* +(my-assert + (let* ((a 1)(b 2) c ) + (declare (integer a b)) + (list a b c)) + (1 2 nil)) + + +(my-assert + (let* ((a 1)(b a)) + (declare (integer a b)) + (list a b)) + (1 1)) + +;; compiler-let (?) + + +;; progv + +(my-assert + (progv + '(a b c) + '(1 2 3) + + (+ a b c)) + 6) + +(unintern 'a) +(unintern 'b) +(unintern 'c) + +(my-assert + (progv + '(a b c) + '(1 2) + + (list a b c)) + error) + +(my-assert + (let ((v '(a b c)) + (val '(3 2 1))) + (progv v val (mapcar #'eval v))) + (3 2 1)) + + +;; flet + +(my-assert + (flet ((plus (a b)(+ a b)) + (minus (a b)(- a b))) + (list (plus 1 2)(minus 1 2))) + (3 -1)) + + +(my-assert + (list (flet ( (+ (a b)(- a b)))(+ 3 2))(+ 3 2)) + (1 5)) + +(my-assert + (flet ((+ (a b)(+ (+ a b a) b)))(+ 3 2)) + 10) + +;; labels +(my-assert + (labels ((queue (l)(if (car l)(queue (cdr l))'ende)))(queue '(1 2 3))) + ende) + +(my-assert + (labels ((+ (a b)(* a (+ a a b))))(+ 1 2 3)) + error) + +;; macrolet ? + + +;; 7.6 + +;; if + +(my-assert + (let ((a t)(b nil))(list (if a 1 2)(if b 1 2)(if a 1)(if b 1))) + (1 2 1 nil)) + + +;; when +(my-assert + (let ((a t)(b nil))(list (when a 1 2)(when b 1 2)(when a 1))) + (2 nil 1)) + + +;; unless +(my-assert + (let ((a t)(b nil))(list (unless a 1 2)(unless b 1 2)(unless a 1))) + (nil 2 nil)) + + +;; cond +(my-assert + (let ((a t)(b 10)(c nil)) + (list (cond (a 1)(t 'end))(cond (b)(t 'end))(cond (c 1)(t 'end)))) + (1 10 end)) + + +;; case +(my-assert + (case (+ 1 2) + (1 -1) + (2 -2) + (3 -3)) + -3) + +(my-assert + (case (+ 1 2) + (1 -1) + (2 -2)) + nil) + + +;; (case (+ 1 2) +;; (1 -1) +;; (2 -2) +;; (1 -1) +;; (3 -3)) +;; error + + +(my-assert + (case (+ 1 2) + ((1 3) -1) + (2 -2) + (otherwise 100)) + -1) + + +;; +;; (case (+ 1 2) +;; ((1 3) -1) +;; ((2 1) -2) +;; (t 100)) +;; error ;weil ein key nur einmal erscheinen darf! +;; + + + +;; typecase + +(my-assert + (typecase (+ 1 2) + (list -2) + (null -3) + (integer -1)) + -1) + +;; 7.7 + +;; block + +(my-assert + (block blocktest (if t (return 0) ) 1) + error) + +(my-assert + (block blocktest (if t (return-from blocktest 0) ) 1) + 0) + + +(my-assert + (block blocktest (if nil (return-from blocktest 0) ) 1) + 1) + + +(my-assert + (block blocktest (catch 'catcher + (if t (throw 'catcher 0) ) 1)) + 0) + + +;; 7.8 + +;; 7.8.1 + +;; loop + +(my-assert + (let ((i 10)) + (loop (if (< (decf i) 1)(return i)))) + 0) + + +(my-assert + (let ((i 10)) + (catch 'catcher + (loop (if (< (decf i) 1)(return i))))) + 0) + +;; 7.8.2 +;; do,do* + +(setf a 0) + +(my-assert + (do ((a 1 (+ a 1))(b a)) + ((> a 9) (list b c)) + (setf c (+ a b))) + (0 9)) + +(my-assert + (do* ((a 1 (+ a 1))(b a)) + ((> a 9) b) + ) + 1) + +(my-assert + (let ((a 0)) + (do* ((a 1 (+ a 1))(b a)) + ((> a 9) a) + (declare (integer a b))) + a) + 0) + + + +;; 7.8.3 + + +;; dolist +(my-assert + (let ((l '(1 2 3)) + (r 0)) + (dolist (x l r) + (setf r (+ r x)) )) + 6) + + +;; dolist +(my-assert + (let ((l '(1 2 3))) + (dolist (x l)(if (> 0 x)(incf x)(return 10)))) + 10) + +(my-assert + (let ((l '(1 2 3))) + (dolist (x l )(incf x))) + nil) + +;; dotimes + +(my-assert + (let ((s 0)) + (dotimes (i (+ 1 9)s) + (setf s (+ s i)))) + 45) + + +;; 7.8.4 + + +;; mapcar + +(my-assert + (mapcar #'abs '(3 -4 2 -5 -6)) + (3 4 2 5 6)) + +(my-assert + (mapcar #'cons '(a b c) '(1 2 3)) + ((a . 1) (b . 2) (c . 3))) + + +;; maplist + +(my-assert + (maplist #'(lambda (x)(cons 'foo x))'(a b c d)) + ((foo a b c d)(foo b c d)(foo c d)(foo d))) + + +(my-assert + (maplist #'(lambda (x) (if (member (car x)(cdr x)) 0 1)) + '(a b a c d b c)) + (0 0 1 0 1 1 1)) + + +;; mapc +(my-assert + (mapc #'abs '(3 -4 2 -5 -6)) + (3 -4 2 -5 -6)) + +;; mapc + +(my-assert + (mapl #'(lambda (x y)(cons x y))'(a b c d)'(1 2 3 4)) + (a b c d)) + +;; mapcan + +(my-assert + (mapcan #'(lambda (x)(and (numberp x)(list x)))'(a 1 b c 3 4 d 5)) + (1 3 4 5)) + +;; mapcon + +(my-assert + (mapcon #'(lambda (x)(and (oddp (car x))(list (car x))))'(5 4 3 2 1)) + (5 3 1)) + +;; 7.8.5 + +;; tagbody +(my-assert + (let ((a 0)) + (tagbody (if nil (go tag0) (go tag1)) + (this will never be reached) + tag0 + (setf a 1) + tag1 + (setf a 2)) + a) + 2) + +(my-assert + (let ((a 0)) + (tagbody (if t (go tag0) (go tag1)) + (this will never be reached) + tag0 + (setf a 1) + ) + a) + ;; cmucl compiles on the fly and therefore signals an error + #-(or cmu sbcl) 1 + #+(or cmu sbcl) error) + + + +;; prog* + +(my-assert + (let ((z '(1 0))) + (prog* ((y z)(x (car y))) + (return x))) + 1) + +(my-assert + (prog (a (b 1)) + (if a (go tag0) (go tag1)) + (this will never be reached) + tag0 + (setf a 1) + (this will never be reached) + tag1 + (setf a 2)) + nil) + + + +(my-assert + (prog (a (b 1)) + (if a (return nil) (go tag1)) + (this will never be reached) + tag0 + (return (list a 1)) + tag1 + (setf a 2) + (go tag0)) + (2 1)) + + +;; 7.9 + +;; multiple-value-bind +(my-assert + (defun adder (x y)(values (+ 1 x)(+ 1 y) ) ) + adder) + + +(my-assert + (multiple-value-bind (a b)(adder 1 2)(+ a b)) + 5) + +(my-assert + (defun adder (x y)(values-list (list (+ 1 x)(+ 1 y)))) + adder) + + +(my-assert + (multiple-value-bind (a b)(adder 1 2)(+ a b)) + 5) + + +(my-assert + (multiple-value-list (floor -3 4)) + (-1 1)) + + +(my-assert + (multiple-value-call #'+ (floor 5 3)(floor 19 4)) + 10) + +(my-assert + (multiple-value-bind (c d) + (multiple-value-prog1 (floor -3 4) (+ 1 2)) + (list c d)) + (-1 1)) + + +(my-assert + (multiple-value-bind (x)(floor 5 3)(list x)) + (1)) + + +(my-assert + (multiple-value-bind (x y)(floor 5 3)(list x y)) + (1 2)) + + +(my-assert + (multiple-value-bind (x y z)(floor 5 3)(list x y z)) + (1 2 nil)) + + + + +(my-assert + (multiple-value-setq + (a b) + (values 10 20)) + 10) + +(my-assert + b + 20) + +(unintern 'a) +(unintern 'b) +;; 7.10 + +;; catch/throw/unwind-protect + diff --git a/src/ansi-tests/streams.lisp b/src/ansi-tests/streams.lisp new file mode 100644 index 000000000..ff3e11bf1 --- /dev/null +++ b/src/ansi-tests/streams.lisp @@ -0,0 +1,1379 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +#+xcl +(my-assert + (progn (in-package 'sys) t) + t) + +#-(or akcl allegro) +(my-assert + (prin1-to-string (make-broadcast-stream)) + #+xcl "#<%TYPE-STRUCTURE-STREAM NIL>" + #+clisp "#" + #+(or cmu sbcl) "#" + #+ecls "#" + #-(or xcl clisp akcl allegro cmu sbcl ecls) unknown) + +(my-assert + (progn (setq s1 (open "d1.plc" :direction :output)) + (setq s2 (open "d2.plc" :direction :output)) + (setq s3 (open "d3.plc" :direction :output)) + (setq b1 (make-broadcast-stream s1 s2 s3 *standard-output*)) t) + t) + +(my-assert + (print "test broadcast satz 1" b1) + "test broadcast satz 1") + +(my-assert + (print "test broadcast satz 2" b1) + "test broadcast satz 2") + +(my-assert + (print "test broadcast satz 3" b1) + "test broadcast satz 3") + +(my-assert + (close s1) + t) + +(my-assert + (close s2) + t) + +(my-assert + (close s3) + t) + +(my-assert + (progn (setq s (open "d1.plc")) t) + t) + +(my-assert + (read s) + "test broadcast satz 1") + +(my-assert + (read s) + "test broadcast satz 2") + +(my-assert + (read s) + "test broadcast satz 3") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d2.plc")) t) + t) + +(my-assert + (read s) + "test broadcast satz 1") + +(my-assert + (read s) + "test broadcast satz 2") + +(my-assert + (read s) + "test broadcast satz 3") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d3.plc")) t) + t) + +(my-assert + (read s) + "test broadcast satz 1") + +(my-assert + (read s) + "test broadcast satz 2") + +(my-assert + (read s) + "test broadcast satz 3") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t0.plc" :direction :output)) t) + t) + +(my-assert + (print (quote read1) s) + read1) + +(my-assert + (print (quote read2) s) + read2) + +(my-assert + (close s) + t) + +(my-assert + (progn (setq inptw (open "t0.plc")) + (setq s1 (open "d1.plc" :direction :output)) + (setq s2 (open "d2.plc" :direction :output)) + (setq sy (make-synonym-stream (quote s2))) + (setq s3 (open "d3.plc" :direction :output)) + (setq tw (make-two-way-stream inptw s3)) + (setq s4 (open "d4.plc" :direction :output)) + (setq ec (make-echo-stream inptw s4)) + (setq s5 (open "d5.plc" :direction :output)) + (setq s6 (open "d6.plc" :direction :output)) + (setq b1 (make-broadcast-stream s5 s6)) + (setq s7 (open "d7.plc" :direction :output)) + (setq b2 (make-broadcast-stream s1 sy tw ec b1 s7)) t) + t) + +(my-assert + (print "w to b2 1.satz" b2) + "w to b2 1.satz") + +(my-assert + (print "w to sy" sy) + "w to sy") + +(my-assert + (print "w to b2 2.satz" b2) + "w to b2 2.satz") + +(my-assert + (print "w to tw" tw) + "w to tw") + +(my-assert + (print "w to b2 3.satz" b2) + "w to b2 3.satz") + +(my-assert + (print "w to ec" ec) + "w to ec") + +(my-assert + (print "w to b2 4.satz" b2) + "w to b2 4.satz") + +(my-assert + (print "w to b1" b1) + "w to b1") + +(my-assert + (print "w to b2 5.satz" b2) + "w to b2 5.satz") + +(my-assert + (print "w to s7" s7) + "w to s7") + +(my-assert + (print "w to b2 6.satz" b2) + "w to b2 6.satz") + +(my-assert + (read tw) + read1) + +(my-assert + (read ec) + read2) + +(my-assert + (print "w to b2 7.satz" b2) + "w to b2 7.satz") + +(my-assert + (print "w to b2 8.satz" b2) + "w to b2 8.satz") + +(my-assert + (close inptw) + t) + +(my-assert + (close s1) + t) + +(my-assert + (close s2) + t) + +(my-assert + (close s3) + t) + +(my-assert + (close s4) + t) + +(my-assert + (close s5) + t) + +(my-assert + (close s6) + t) + +(my-assert + (close s7) + t) + +(my-assert + (progn (setq s (open "d1.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d2.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to sy") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d3.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to tw") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d4.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to ec") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + read2) + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d5.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b1") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d6.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b1") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "d7.plc")) t) + t) + +(my-assert + (read s) + "w to b2 1.satz") + +(my-assert + (read s) + "w to b2 2.satz") + +(my-assert + (read s) + "w to b2 3.satz") + +(my-assert + (read s) + "w to b2 4.satz") + +(my-assert + (read s) + "w to b2 5.satz") + +(my-assert + (read s) + "w to s7") + +(my-assert + (read s) + "w to b2 6.satz") + +(my-assert + (read s) + "w to b2 7.satz") + +(my-assert + (read s) + "w to b2 8.satz") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t1.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t1" s) + "1.satz t1") + +(my-assert + (print "2.satz t1" s) + "2.satz t1") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t2.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t2" s) + "1.satz t2") + +(my-assert + (print "2.satz t2" s) + "2.satz t2") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t3.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t3" s) + "1.satz t3") + +(my-assert + (print "2.satz t3" s) + "2.satz t3") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t4.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t4" s) + "1.satz t4") + +(my-assert + (print "2.satz t4" s) + "2.satz t4") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t5.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t5" s) + "1.satz t5") + +(my-assert + (print "2.satz t5" s) + "2.satz t5") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t6.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t6" s) + "1.satz t6") + +(my-assert + (print "2.satz t6" s) + "2.satz t6") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t7.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t7" s) + "1.satz t7") + +(my-assert + (print "2.satz t7" s) + "2.satz t7") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t8.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t8" s) + "1.satz t8") + +(my-assert + (print "2.satz t8" s) + "2.satz t8") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t9.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t9" s) + "1.satz t9") + +(my-assert + (print "2.satz t9" s) + "2.satz t9") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s (open "t10.plc" :direction :output)) t) + t) + +(my-assert + (print "1.satz t10" s) + "1.satz t10") + +(my-assert + (print "2.satz t10" s) + "2.satz t10") + +(my-assert + (close s) + t) + +(my-assert + (progn (setq s1 (open "t1.plc")) (setq s2 (open "t2.plc")) + (setq s3 (open "t3.plc")) (setq s4 (open "t4.plc")) (setq s5 (open + "t5.plc")) + (setq c1 (make-concatenated-stream s1 s2 s3)) + (setq c2 (make-concatenated-stream s4 s5)) t) + t) + +(my-assert + (read c1) + "1.satz t1") + +(my-assert + (read c2) + "1.satz t4") + +(my-assert + (read c1) + "2.satz t1") + +(my-assert + (read c1) + "1.satz t2") + +(my-assert + (read c2) + "2.satz t4") + +(my-assert + (read c2) + "1.satz t5") + +(my-assert + (read c1) + "2.satz t2") + +(my-assert + (read c1) + "1.satz t3") + +(my-assert + (read c1) + "2.satz t3") + +(my-assert + (read c2) + "2.satz t5") + +(my-assert + (close s1) + t) + +(my-assert + (close s2) + t) + +(my-assert + (close s3) + t) + +(my-assert + (close s4) + t) + +(my-assert + (close s5) + t) + +(my-assert + (progn (setq s1 (open "t1.plc")) (setq s2 (open "t2.plc")) + (setq s3 (open "t3.plc")) (setq s4 (open "t4.plc")) (setq s5 (open + "t5.plc")) + (setq s6 (open "t6.plc")) (setq s7 (open "t7.plc")) (setq s8 (open + "t8.plc")) + (setq s9 (open "t9.plc")) (setq s10 (open "t10.plc")) + (setq c1 (make-concatenated-stream s1 s2)) + (setq c2 (make-concatenated-stream s3)) + (setq c3 (make-concatenated-stream c1 c2 s4)) + (setq c4 (make-concatenated-stream s5 s6 s7 s8 s9 s10)) t) + t) + +(my-assert + (read c4) + "1.satz t5") + +(my-assert + (read c3) + "1.satz t1") + +(my-assert + (read c4) + "2.satz t5") + +(my-assert + (read c4) + "1.satz t6") + +(my-assert + (read c3) + "2.satz t1") + +(my-assert + (read c3) + "1.satz t2") + +(my-assert + (read c4) + "2.satz t6") + +(my-assert + (read c4) + "1.satz t7") + +(my-assert + (read c4) + "2.satz t7") + +(my-assert + (read c3) + "2.satz t2") + +(my-assert + (read c3) + "1.satz t3") + +(my-assert + (read c3) + "2.satz t3") + +(my-assert + (read c4) + "1.satz t8") + +(my-assert + (read c4) + "2.satz t8") + +(my-assert + (read c4) + "1.satz t9") + +(my-assert + (read c4) + "2.satz t9") + +(my-assert + (read c3) + "1.satz t4") + +(my-assert + (read c3) + "2.satz t4") + +(my-assert + (read c4) + "1.satz t10") + +(my-assert + (read c4) + "2.satz t10") + +(my-assert + (close s1) + t) + +(my-assert + (close s2) + t) + +(my-assert + (close s3) + t) + +(my-assert + (close s4) + t) + +(my-assert + (close s5) + t) + +(my-assert + (close s6) + t) + +(my-assert + (close s7) + t) + +(my-assert + (close s8) + t) + +(my-assert + (close s9) + t) + +(my-assert + (close s10) + t) + +(my-assert + (setq str1 "test 123456") + "test 123456") + +(my-assert + (progn (setq s1 (make-string-input-stream str1)) t) + t) + +(my-assert + (read s1) + test) + +(my-assert + (read-char s1) + #\1) + +(my-assert + (read-char s1) + #\2) + +(my-assert + (unread-char #\2 s1) + nil) + +(my-assert + (read-char s1) + #\2) + +(my-assert + (read-char s1) + #\3) + +(my-assert + (read-char s1) + #\4) + +(my-assert + (unread-char #\a s1) + error + "We previously read #\4 from S1, we are not allowed to +put #\a back in!") + +(my-assert + (read-char s1) + #\5 + "The previous unread-char should have failed, so +we expect to see #\5 here. If the unread-char worked +we will (wrongly!) see #\4 or #\a") + +(my-assert + (read-char s1) + #\6 + "Likewise the unread-char should have failed") + +(my-assert + (close s1) + t) + +(my-assert + str1 + "test 123456") + +(my-assert + (multiple-value-list (read-from-string "012345 789")) + (12345 7)) + +(my-assert + (multiple-value-list (read-from-string "012345 789" t nil + :preserve-whitespace t)) + (12345 6)) + +(my-assert + (multiple-value-list (read-from-string "012345 789" t nil :end 4)) + (123 4)) + +(my-assert + (multiple-value-list (read-from-string "012345 789" t nil :start 2)) + (2345 7)) + +(my-assert + (progn (setq strgstream (make-string-input-stream "0123456789" 5 8)) + t) + t) + +(my-assert + (read strgstream) + 567) + +(my-assert + (progn (setq strgstream + (make-string-input-stream "wenn alles gut geht ist das ein stream 012")) + t) + t) + +(my-assert + (read strgstream) + wenn) + +(my-assert + (read strgstream) + alles) + +(my-assert + (read strgstream) + gut) + +(my-assert + (read strgstream) + geht) + +(my-assert + (read strgstream) + ist) + +(my-assert + (read strgstream) + das) + +(my-assert + (read strgstream) + ein) + +(my-assert + (read strgstream) + stream) + +(my-assert + (read strgstream) + 12) + +(my-assert + (progn (setq strgstream (make-string-output-stream)) t) + t) + +(my-assert + (princ "das " strgstream) + "das ") + +(my-assert + (princ "ist " strgstream) + "ist ") + +(my-assert + (princ "ein " strgstream) + "ein ") + +(my-assert + (princ "string " strgstream) + "string ") + +(my-assert + (princ "output " strgstream) + "output ") + +(my-assert + (princ "stream " strgstream) + "stream ") + +(my-assert + (get-output-stream-string strgstream) + "das ist ein string output stream ") + +(my-assert + (get-output-stream-string strgstream) + "") + +(my-assert + (princ "das ist ein neuer string output stream" strgstream) + "das ist ein neuer string output stream") + +(my-assert + (get-output-stream-string strgstream) + "das ist ein neuer string output stream") + +(my-assert + (setq *print-length* 50) + 50) + +(my-assert + (write-to-string 123456789) + "123456789") + +(my-assert + "(write-to-string '#1=(123456789 . #1#))" + "(write-to-string '#1=(123456789 . #1#))") + +(my-assert + (prin1-to-string "abc") + "\"abc\"") + +(my-assert + (princ-to-string "abc") + "abc") + +(my-assert + (progn (setq os (make-string-output-stream)) t) + t) + +(my-assert + (setq s50 "123456789A123456789B123456789C123456789D12345678 +E") + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (setq s49 "123456789A123456789B123456789C123456789D1234567 +*") + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s49 os) + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (princ "A" os) + "A") + +(my-assert + (princ "B" os) + "B") + +(my-assert + (princ "C" os) + "C") + +(my-assert + (length (princ (get-output-stream-string os))) + 402) + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s50 os) + "123456789A123456789B123456789C123456789D12345678 +E") + +(my-assert + (princ s49 os) + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (princ s49 os) + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (princ s49 os) + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (princ s49 os) + "123456789A123456789B123456789C123456789D1234567 +*") + +(my-assert + (length (princ (get-output-stream-string os))) + 496) + +(my-assert + (progn (setq os (open "d0.plc" :direction :output)) + (setq os1 (open "d1.plc" :direction :output)) + (setq is (open "t0.plc" :direction :output)) t) + t) + +(my-assert + (princ "'(a b #.(print \"1.zwischenwert\" os1) c d)" is) + "'(a b #.(print \"1.zwischenwert\" os1) c d)") + +(my-assert + (princ "'(a b #.(prin1-to-string \"2.zwischenwert\") c d)" is) + "'(a b #.(prin1-to-string \"2.zwischenwert\") c d)") + +(my-assert + (princ "'(a b #.(format nil \"3.zwischenwert\") c d)" is) + "'(a b #.(format nil \"3.zwischenwert\") c d)") + +(my-assert + (close is) + t) + +(my-assert + (progn (setq is (open "t0.plc")) (setq es (make-echo-stream is os)) + t) + t) + +(my-assert + (print "ausgabe os1" os1) + "ausgabe os1") + +(my-assert + (read es) + (quote (a b "1.zwischenwert" c d))) + +(my-assert + (print "ausgabe os1" os1) + "ausgabe os1") + +(my-assert + (read es) + (quote (a b "\"2.zwischenwert\"" c d))) + +(my-assert + (print "ausgabe os1" os1) + "ausgabe os1") + +(my-assert + (read es) + (quote (a b "3.zwischenwert" c d))) + +(my-assert + (print "ausgabe os1" os1) + "ausgabe os1") + +(my-assert + (close is) + t) + +(my-assert + (close os) + t) + +(my-assert + (progn (setq is (open "d0.plc")) t) + t) + +(my-assert + (read is) + (quote (a b "1.zwischenwert" c d))) + +(my-assert + (read is) + (quote (a b "\"2.zwischenwert\"" c d))) + +(my-assert + (read is) + (quote (a b "3.zwischenwert" c d))) + +(my-assert + (close is) + t) + +(my-assert + (close os1) + t) + +(my-assert + (progn (setq is (open "d1.plc")) t) + t) + +(my-assert + (read is) + "ausgabe os1") + +(my-assert + (read is) + "1.zwischenwert") + +(my-assert + (read is) + "ausgabe os1") + +(my-assert + (read is) + "ausgabe os1") + +(my-assert + (read is) + "ausgabe os1") + +(my-assert + (read is) + "1.zwischenwert") + +(my-assert + (close is) + t) + +(my-assert + (progn (mapc #'delete-file (directory "*.plc")) t) + t) + +(my-assert + (progn + (makunbound 's) + (makunbound 's1) + (makunbound 's2) + (makunbound 's3) + (makunbound 's4) + (makunbound 's5) + (makunbound 's6) + (makunbound 's7) + (makunbound 's8) + (makunbound 's9) + (makunbound 's10) + (makunbound 'b1) + (makunbound 'b2) + (makunbound 'c1) + (makunbound 'c2) + (makunbound 'c3) + (makunbound 'c4) + (makunbound 'inptw) + (makunbound 'sy) + (makunbound 'tw) + (makunbound 'ec) + (makunbound 'str1) + (makunbound 'strgstream) + (makunbound 'os) + (makunbound 'os1) + (makunbound 'is) + (makunbound 'es) + (makunbound 's50) + (makunbound 's49) + (setq *print-length* nil) + t) + t) + diff --git a/src/ansi-tests/streamslong.lisp b/src/ansi-tests/streamslong.lisp new file mode 100644 index 000000000..50daee978 --- /dev/null +++ b/src/ansi-tests/streamslong.lisp @@ -0,0 +1,31 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (read-from-string "123") + 123) + +(my-assert + (prin1-to-string 123) + "123") + +(my-assert + (let ((*a* + (make-array 10. :element-type 'character + :fill-pointer 0))) + (format *a* "XXX")) + nil) + +(my-assert + (let ((*a* + (make-array 10. :element-type 'character + :fill-pointer 0))) + (format *a* "XXX") + *a*) + "XXX") + +#+xcl +(my-assert + (sys::check-stream-system) + #+xcl t) + diff --git a/src/ansi-tests/strings.lisp b/src/ansi-tests/strings.lisp new file mode 100644 index 000000000..9e1246e44 --- /dev/null +++ b/src/ansi-tests/strings.lisp @@ -0,0 +1,1600 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (char "abcdef-dg1ndh" 0) + #\a) + +(my-assert + (char "abcdef-dg1ndh" 1) + #\b) + +(my-assert + (char "abcdef-dg1ndh" 6) + #\-) + +(my-assert + (char "abcdef-dg1ndh" 20) + error) + +(my-assert + (char "abcdef-dg1ndh") + program-error) + +(my-assert + (char "abcdef-dg1ndh" -3) + error) + +(my-assert + (char) + program-error) + +(my-assert + (char 2) + program-error) + +(my-assert + (char "abcde" 2 4) + error) + +(my-assert + (char 'a 0) + #+xcl #\a + #-xcl error) + +(my-assert + (char 'anna 0) + #+xcl #\a + #-xcl error) + +(my-assert + (schar 'a 0) + #+xcl #\a + #-xcl error) + +(my-assert + (schar 'anna 0) + #+xcl #\a + #-xcl error) + +(my-assert + (schar "abcdef-dg1ndh" 0) + #\a) + +(my-assert + (schar "abcdef-dg1ndh" 1) + #\b) + +(my-assert + (schar "abcdef-dg1ndh" 6) + #\-) + +(my-assert + (schar "abcdef-dg1ndh" 20) + error) + +(my-assert + (schar "abcdef-dg1ndh") + program-error) + +(my-assert + (schar "abcdef-dg1ndh" -3) + error) + +(my-assert + (schar 2) + program-error) + +(my-assert + (schar 2 2) + error) + +(my-assert + (schar "abcde" 2 4) + program-error) + +(my-assert + (string= "foo" "foo") + t) + +(my-assert + (string= "foo" "Foo") + nil) + +(my-assert + (string= "foo" "FOO") + nil) + +(my-assert + (string= "foo" "bar") + nil) + +(my-assert + (string= "together" "frog" :start1 1 :end1 3 :start2 2) + t) + +(my-assert + (string= "abcdef" "defghi" :start1 3 :end2 3) + t) + +(my-assert + (string= "abcdefghi" "uvdefmgnj" :start1 3 :end1 6 :start2 2 :end2 + 5) + t) + +(my-assert + (string= "abcdefg" "abcdefg" :end2 4) + nil) + +(my-assert + (string= "abcdef" "abcdef" :start1 1 :end1 4 :start2 4 :end2 1) + error) + +(my-assert + (string-equal "foo" "foo") + t) + +(my-assert + (string-equal "foo" "Foo") + t) + +(my-assert + (string-equal "foo" "FOO") + t) + +(my-assert + (string-equal "foo" "bar") + nil) + +(my-assert + (string-equal "absDEfg-HijM1#r" "udEFG-hIfvd" :start1 3 :end1 10 :start2 + 1 :end2 + 8) + t) + +(my-assert + (string-equal "ABCdefg" "abcDEFG") + t) + +(my-assert + (string-equal "ABCdefg" "abcDEFG" :start1 3) + nil) + +(my-assert + (string-equal "AbCdEf" "aBcDeF" :start1 5 :end1 3) + error) + +(my-assert + (string< "" "abcdefgh") + 0) + +(my-assert + (string< "a" "abcdefgh") + 1) + +(my-assert + (string< "abc" "abcdefgh") + 3) + +(my-assert + (string< "cabc" "abcdefgh") + nil) + +(my-assert + (string< "abcdefgh" "abcdefgh") + nil) + +(my-assert + (string< "xyzabc" "abcdefgh") + nil) + +(my-assert + (string< "abc" "xyzabcdefgh") + 0) + +(my-assert + (string< "abcdefgh" "abcdefgh" :end1 4) + 4) + +(my-assert + (string< "xyzabc" "abcdefgh" :start1 3) + 6) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string< "abcdefgh" "") + nil) + +(my-assert + (string< "abcdefgh" "a") + nil) + +(my-assert + (string< "abcdefgh" "abc") + nil) + +(my-assert + (string< "abcdefgh" "cabc") + 0) + +(my-assert + (string< "abcdefgh" "xyzabc") + 0) + +(my-assert + (string< "xyzabcdefgh" "abc") + nil) + +(my-assert + (string< "abcdefgh" "abcdefgh" :end2 4) + nil) + +(my-assert + (string< "xyzabc" "abcdefgh" :start2 3) + nil) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string< "abc" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string< "abcdef" "bcdefgh") + 0) + +(my-assert + (string< "abcdef" "abcdefgh" :start2 2) + 0) + +(my-assert + (string< "abcdef" "bngdabcdef" :start2 9 :end2 5) + error) + +(my-assert + (string> "" "abcdefgh") + nil) + +(my-assert + (string> "a" "abcdefgh") + nil) + +(my-assert + (string> "abc" "abcdefgh") + nil) + +(my-assert + (string> "cabc" "abcdefgh") + 0) + +(my-assert + (string> "abcdefgh" "abcdefgh") + nil) + +(my-assert + (string> "xyzabc" "abcdefgh") + 0) + +(my-assert + (string> "abc" "xyzabcdefgh") + nil) + +(my-assert + (string> "abcdefgh" "abcdefgh" :end1 4) + nil) + +(my-assert + (string> "xyzabc" "abcdefgh" :start1 3) + nil) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string> "abcdefgh" "") + 0) + +(my-assert + (string> "abcdefgh" "a") + 1) + +(my-assert + (string> "abcdefgh" "abc") + 3) + +(my-assert + (string> "abcdefgh" "cabc") + nil) + +(my-assert + (string> "abcdefgh" "xyzabc") + nil) + +(my-assert + (string> "xyzabcdefgh" "abc") + 0) + +(my-assert + (string> "abcdefgh" "abcdefgh" :end2 4) + 4) + +(my-assert + (string> "xyzabc" "abcdefgh" :start2 3) + 0) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string> "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string> "abcde" "bc") + nil) + +(my-assert + (string> "bcdef" "abcde") + 0) + +(my-assert + (string> "bcdef" "abcdef") + 0) + +(my-assert + (string> "abcdefghij" "abcdefgh" :start1 1) + 1) + +(my-assert + (string> "ghijkl" "xyzabcd" :start2 6 :end2 4) + error) + +(my-assert + (string< "" "abcdefgh") + 0) + +(my-assert + (string<= "a" "abcdefgh") + 1) + +(my-assert + (string<= "abc" "abcdefgh") + 3) + +(my-assert + (string<= "aaabce" "aaabcdefgh") + nil) + +(my-assert + (string<= "cabc" "abcdefgh") + nil) + +(my-assert + (string<= "abcdefgh" "abcdefgh") + 8) + +(my-assert + (string<= "xyzabc" "abcdefgh") + nil) + +(my-assert + (string<= "abc" "xyzabcdefgh") + 0) + +(my-assert + (string<= "abcdefgh" "abcdefgh" :end1 4) + 4) + +(my-assert + (string<= "xyzabc" "abcdefgh" :start1 3) + 6) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string<= "abcdefgh" "") + nil) + +(my-assert + (string<= "abcdefgh" "a") + nil) + +(my-assert + (string<= "abcdefgh" "abc") + nil) + +(my-assert + (string<= "abcdefgh" "cabc") + 0) + +(my-assert + (string<= "abcdefgh" "xyzabc") + 0) + +(my-assert + (string<= "xyzabcdefgh" "abc") + nil) + +(my-assert + (string<= "abcdefgh" "abcdefgh" :end2 4) + nil) + +(my-assert + (string<= "xyzabc" "abcdefgh" :start2 3) + nil) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string<= "abc" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string<= "abcdef" "bcdefgh") + 0) + +(my-assert + (string<= "abcdef" "abcdefgh" :start2 2) + 0) + +(my-assert + (string<= "abcdef" "bngdabcdef" :start2 9 :end2 5) + error) + + +(my-assert + (string>= "" "abcdefgh") + nil) + +(my-assert + (string>= "a" "abcdefgh") + nil) + +(my-assert + (string>= "abc" "abcdefgh") + nil) + +(my-assert + (string>= "cabc" "abcdefgh") + 0) + +(my-assert + (string>= "abcdefgh" "abcdefgh") + 8) + +(my-assert + (string>= "xyzabc" "abcdefgh") + 0) + +(my-assert + (string>= "abc" "xyzabcdefgh") + nil) + +(my-assert + (string>= "abcdefgh" "abcdefgh" :end1 4) + nil) + +(my-assert + (string>= "xyzabc" "abcdefgh" :start1 3) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string>= "abcdefgh" "") + 0) + +(my-assert + (string>= "abcdefgh" "a") + 1) + +(my-assert + (string>= "abcdefgh" "abc") + 3) + +(my-assert + (string>= "abcdefgh" "cabc") + nil) + +(my-assert + (string>= "abcdefgh" "xyzabc") + nil) + +(my-assert + (string>= "xyzabcdefgh" "abc") + 0) + +(my-assert + (string>= "abcdefgh" "abcdefgh" :end2 4) + 4) + +(my-assert + (string>= "xyzabc" "abcdefgh" :start2 3) + 0) + +(my-assert + (string>= "xyzabc" "abcdefgh" :start1 3) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string>= "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string>= "bcdef" "abcdef") + 0) + +(my-assert + (string>= "abcdefghij" "abcdefgh" :start1 1) + 1) + +(my-assert + (string>= "ghijkl" "xyzabcd" :start2 6 :end2 4) + error) + +(my-assert + (string/= "" "abcdefgh") + 0) + +(my-assert + (string/= "a" "abcdefgh") + 1) + +(my-assert + (string/= "abc" "abcdefgh") + 3) + +(my-assert + (string/= "cabc" "abcdefgh") + 0) + +(my-assert + (string/= "abcdefgh" "abcdefgh") + nil) + +(my-assert + (string/= "xyzabc" "abcdefgh") + 0) + +(my-assert + (string/= "abc" "xyzabcdefgh") + 0) + +(my-assert + (string/= "abcdefgh" "abcdefgh" :end1 4) + 4) + +(my-assert + (string/= "xyzabc" "abcdefgh" :start1 3) + 6) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string/= "abcdefgh" "") + 0) + +(my-assert + (string/= "abcdefgh" "a") + 1) + +(my-assert + (string/= "abcdefgh" "abc") + 3) + +(my-assert + (string/= "abcdefgh" "cabc") + 0) + +(my-assert + (string/= "abcdefgh" "xyzabc") + 0) + +(my-assert + (string/= "xyzabcdefgh" "abc") + 0) + +(my-assert + (string/= "abcdefgh" "abcdefgh" :end2 4) + 4) + +(my-assert + (string/= "xyzabc" "abcdefgh" :start2 3) + 0) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string/= "abc" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string/= "abcdefghi" "uvdefmgnj" :start1 3 :end1 6 :start2 2 :end2 5) + nil) + +(my-assert + (string/= "abcdefg" "abcdefg" :end2 4) + 4) + +(my-assert + (string/= "abcdef" "abcdef" :start1 1 :end1 4 :start2 4 :end2 1) + error) + +(my-assert + (string-lessp "" "abcDEFgh") + 0) + +(my-assert + (string-lessp "a" "Abcdefgh") + 1) + +(my-assert + (string-lessp "abc" "aBcDEfgh") + 3) + +(my-assert + (string-lessp "cABc" "aBCDefgh") + nil) + +(my-assert + (string-lessp "abCDeFgh" "abCDEfgh") + nil) + +(my-assert + (string-lessp "xyzAbc" "ABcCDfgh") + nil) + +(my-assert + (string-lessp "aBC" "xYZAbcdEfgh") + 0) + +(my-assert + (string-lessp "abcDEfgh" "abcDEfgh" :end1 4) + 4) + +(my-assert + (string-lessp "XYZabc" "ABcdefgh" :start1 3) + 6) + +(my-assert + (string-lessp "aBc" "xyZABcdefgh" :start2 3) + 3) + +(my-assert + (string-lessp "abc" "xyzabCDEcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-lessp "abc" "xyzABcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string-lessp "abcdefgh" "") + nil) + +(my-assert + (string-lessp "Abcdefgh" "a") + nil) + +(my-assert + (string-lessp "ABCdefgh" "abc") + nil) + +(my-assert + (string-lessp "ABCdefgh" "cabc") + 0) + +(my-assert + (string-lessp "abcdefgh" "xyzABC") + 0) + +(my-assert + (string-lessp "xyzABCdefgh" "abc") + nil) + +(my-assert + (string-lessp "abcdEFgh" "abcdeFGh" :end2 4) + nil) + +(my-assert + (string-lessp "xyzaBC" "abCDefgh" :start2 3) + nil) + +(my-assert + (string-lessp "ABC" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string-lessp "aBCDef" "bcdefgh") + 0) + +(my-assert + (string-lessp "aBCDef" "abcdefgh" :start2 2) + 0) + +(my-assert + (string-lessp "aBCDef" "bngdabcdef" :start2 9 :end2 5) + error) + +(my-assert + (string-greaterp "" "abcdefgh") + nil) + +(my-assert + (string-greaterp "A" "abcdefgh") + nil) + +(my-assert + (string-greaterp "ABc" "abcdefgh") + nil) + +(my-assert + (string-greaterp "CAbc" "abcdefgh") + 0) + +(my-assert + (string-greaterp "abcdefgh" "abcDEFgh") + nil) + +(my-assert + (string-greaterp "xyzabc" "abCDEfgh") + 0) + +(my-assert + (string-greaterp "ABC" "xyzabcdefgh") + nil) + +(my-assert + (string-greaterp "ABCdefgh" "abcdefgh" :end1 4) + nil) + +(my-assert + (string-greaterp "xyzaBc" "ABCdefgh" :start1 3) + nil) + +(my-assert + (string-greaterp "abc" "xyzABcdefgh" :start2 3) + nil) + +(my-assert + (string-greaterp "abc" "xyzABcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string-greaterp "abc" "xyZAbcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string-greaterp "abcdefgh" "") + 0) + +(my-assert + (string-greaterp "Abcdefgh" "a") + 1) + +(my-assert + (string-greaterp "ABCdefgh" "abc") + 3) + +(my-assert + (string-greaterp "ABCdefgh" "cabc") + nil) + +(my-assert + (string-greaterp "ABCdefgh" "xyzabc") + nil) + +(my-assert + (string-greaterp "xyzabcdefgh" "Abc") + 0) + +(my-assert + (string-greaterp "abcdefgh" "aBCDefgh" :end2 4) + 4) + +(my-assert + (string-greaterp "xyzabc" "abcdEFgh" :start2 3) + 0) + +(my-assert + (string-greaterp "ABC" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string-greaterp "bCDEf" "abcde") + 0) + +(my-assert + (string-greaterp "bcDEF" "abcdef") + 0) + +(my-assert + (string-greaterp "abCDEfghij" "abcdefgh" :start1 1) + 1) + +(my-assert + (string-greaterp "ghijKl" "xyzabcd" :start2 6 :end2 4) + error) + +(my-assert + (string-not-greaterp "" "abcdefgh") + 0) + +(my-assert + (string-not-greaterp "A" "abcdefgh") + 1) + +(my-assert + (string-not-greaterp "aBC" "abcdefgh") + 3) + +(my-assert + (string-not-greaterp "CABc" "abcdefgh") + nil) + +(my-assert + (string-not-greaterp "abcDEFgh" "abcdefgh") + 8) + +(my-assert + (string-not-greaterp "xyzabc" "ABcdefgh") + nil) + +(my-assert + (string-not-greaterp "abc" "xyzABcdefgh") + 0) + +(my-assert + (string-not-greaterp "ABCDEFgh" "abcdefgh" :end1 4) + 4) + +(my-assert + (string-not-greaterp "xyzabc" "aBCDefgh" :start1 3) + 6) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string-not-greaterp "abcdefgh" "") + nil) + +(my-assert + (string-not-greaterp "Abcdefgh" "a") + nil) + +(my-assert + (string-not-greaterp "ABCdefgh" "abc") + nil) + +(my-assert + (string-not-greaterp "ABCdefgh" "cabc") + 0) + +(my-assert + (string-not-greaterp "ABCdefgh" "xyzabc") + 0) + +(my-assert + (string-not-greaterp "xyzABCdefgh" "abc") + nil) + +(my-assert + (string-not-greaterp "abcdeFgh" "abcdefgh" :end2 4) + nil) + +(my-assert + (string-not-greaterp "xyzABC" "abcdefgh" :start2 3) + nil) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-not-greaterp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + nil) + +(my-assert + (string-not-greaterp "abcDEF" "bcdefgh") + 0) + +(my-assert + (string-not-greaterp "abcDEF" "abcdefgh" :start2 2) + 0) + +(my-assert + (string-not-greaterp "abcdef" "bngDAbcdef" :start2 9 :end2 5) + error) + +(my-assert + (string-not-lessp "" "abcdefgh") + nil) + +(my-assert + (string-not-lessp "a" "Abcdefgh") + nil) + +(my-assert + (string-not-lessp "ABC" "abcdefgh") + nil) + +(my-assert + (string-not-lessp "CABc" "abcdefgh") + 0) + +(my-assert + (string-not-lessp "ABCdefgh" "abcdefgh") + 8) + +(my-assert + (string-not-lessp "xyzABC" "abcdefgh") + 0) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh") + nil) + +(my-assert + (string-not-lessp "ABCdefgh" "abcdefgh" :end1 4) + nil) + +(my-assert + (string-not-lessp "xyzABC" "abcdefgh" :start1 3) + nil) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string-not-lessp "abcdefgh" "") + 0) + +(my-assert + (string-not-lessp "Abcdefgh" "a") + 1) + +(my-assert + (string-not-lessp "ABCdefgh" "abc") + 3) + +(my-assert + (string-not-lessp "abCDEfgh" "cabc") + nil) + +(my-assert + (string-not-lessp "aBCdefgh" "xyzabc") + nil) + +(my-assert + (string-not-lessp "xyzABcdefgh" "abc") + 0) + +(my-assert + (string-not-lessp "abCDEfgh" "abcdefgh" :end2 4) + 4) + +(my-assert + (string-not-lessp "xyzABc" "abcdefgh" :start2 3) + 0) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3) + nil) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 8) + nil) + +(my-assert + (string-not-lessp "ABC" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string-not-lessp "bCDef" "abcdef") + 0) + +(my-assert + (string-not-lessp "ABCdefghij" "abcdefgh" :start1 1) + 1) + +(my-assert + (string-not-lessp "ghIjkl" "xyzabcd" :start2 6 :end2 4) + error) + +(my-assert + (string-not-equal "" "abcdefgh") + 0) + +(my-assert + (string-not-equal "A" "abcdefgh") + 1) + +(my-assert + (string-not-equal "ABc" "abcdefgh") + 3) + +(my-assert + (string-not-equal "cABc" "abcdefgh") + 0) + +(my-assert + (string-not-equal "ABCdefgh" "abcdefgh") + nil) + +(my-assert + (string-not-equal "xyzABc" "abcdefgh") + 0) + +(my-assert + (string-not-equal "ABC" "xyzabcdefgh") + 0) + +(my-assert + (string-not-equal "ABCdefgh" "abcdefgh" :end1 4) + 4) + +(my-assert + (string-not-equal "xyzaBC" "abcdefgh" :start1 3) + 6) + +(my-assert + (string-not-equal "ABC" "xyzabcdefgh" :start2 3) + 3) + +(my-assert + (string-not-equal "ABC" "xyzabcdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-not-equal "ABC" "xyzabcdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string-not-equal "abcdefgh" "") + 0) + +(my-assert + (string-not-equal "Abcdefgh" "a") + 1) + +(my-assert + (string-not-equal "aBCdefgh" "abc") + 3) + +(my-assert + (string-not-equal "abcdefgh" "cABc") + 0) + +(my-assert + (string-not-equal "abcdefgh" "xyzAbc") + 0) + +(my-assert + (string-not-equal "xyzabcdefgh" "ABC") + 0) + +(my-assert + (string-not-equal "abcdefgh" "abcDEFgh" :end2 4) + 4) + +(my-assert + (string-not-equal "xyzabc" "aBCDefgh" :start2 3) + 0) + +(my-assert + (string-not-equal "abc" "xyzABCdefgh" :start2 3) + 3) + +(my-assert + (string-not-equal "abc" "xyzABCdefgh" :start2 3 :end2 8) + 3) + +(my-assert + (string-not-equal "abc" "xyzABCdefgh" :start2 3 :end2 5) + 2) + +(my-assert + (string/= "abcdefghi" "uvdEFmgnj" :start1 3 :end1 6 :start2 2 :end2 5) + 4) + +(my-assert + (string/= "abcdefg" "abcDEfg" :end2 4) + 3) + +(my-assert + (string/= "abcdef" "abCDef" :start1 1 :end1 4 :start2 4 :end2 1) + error) + +(my-assert + (string-trim (quote (#\space #\tab #\newline)) " garbanzo beans + ") + "garbanzo beans") + +(my-assert + (string-trim " (*)" " ( *three(siily) words* ) ") + "three(siily) words") + +(my-assert + (string-trim (quote a) "ababa") + error) + +(my-assert + (string-trim (quote (a)) "ababa") + #+xcl error + #+(or clisp gcl allegro cmu ecls) "ababa" + #-(or xcl clisp gcl allegro cmu ecls) unknown) + +(my-assert + (string-trim "a" "ababa") + "bab") + +(my-assert + (string-trim "c e" " ceabceabce c") + "abceab") + +(my-assert + (string-trim (quote (#\a)) "abcd") + "bcd") + +(my-assert + (string-trim (quote (#\a)) "xyzabcd") + "xyzabcd") + +(my-assert + (string-trim (quote (#\a)) "abcda") + "bcd") + +(my-assert + (string-left-trim (quote (#\space #\tab #\newline)) " garbanzo beans + ") + "garbanzo beans + ") + +(my-assert + (string-left-trim " (*)" " ( *three(siily) words* ) ") + "three(siily) words* ) ") + +(my-assert + (string-left-trim (quote a) "ababa") + error) + +(my-assert + (string-left-trim (quote (a)) "ababa") + #+xcl error + #+(or clisp gcl allegro cmu ecls) "ababa" + #-(or xcl clisp gcl allegro cmu ecls) unknown) + +(my-assert + (string-left-trim "a" "ababa") + "baba") + +(my-assert + (string-left-trim "c e" " ceabceabce c") + "abceabce c") + +(my-assert + (string-left-trim (quote (#\a)) "abcd") + "bcd") + +(my-assert + (string-left-trim (quote (#\a)) "xyzabcd") + "xyzabcd") + +(my-assert + (string-left-trim (quote (#\a)) "abcda") + "bcda") + +(my-assert + (string-right-trim (quote (#\space #\tab #\newline)) " garbanzo beans + ") + " garbanzo beans") + +(my-assert + (string-right-trim " (*)" " ( *three(siily) words* ) ") + " ( *three(siily) words") + +(my-assert + (string-right-trim (quote a) "ababa") + error) + +(my-assert + (string-right-trim (quote (a)) "ababa") + #+xcl error + #+(or clisp gcl allegro cmu ecls) "ababa" + #-(or xcl clisp gcl allegro cmu ecls) unknown) + +(my-assert + (string-right-trim "a" "ababa") + "abab") + +(my-assert + (string-right-trim "c e" " ceabceabce c") + " ceabceab") + +(my-assert + (string-right-trim (quote (#\a)) "abcd") + "abcd") + +(my-assert + (string-right-trim (quote (#\a)) "xyzabcd") + "xyzabcd") + +(my-assert + (string-right-trim (quote (#\a)) "abcda") + "abcd") + +(my-assert + (string-upcase "abCD efGh-ij") + "ABCD EFGH-IJ") + +(my-assert + (string-upcase "abCD efGh-ij" :start 5) + "abCD EFGH-IJ") + +(my-assert + (string-upcase "abCD efGh-ij" :end 5) + "ABCD efGh-ij") + +(my-assert + (string-upcase "abCD efGh-ij" :start 1 :end 6) + "aBCD EfGh-ij") + +(my-assert + (string-upcase "abCD efGh-ij" :start 6 :end 1) + error) + +(my-assert + (string-upcase "abCD efGh-ij" :start 3 :end 3) + "abCD efGh-ij") + +(my-assert + (string-downcase "abCD efGh-ij") + "abcd efgh-ij") + +(my-assert + (string-downcase "abCD efGh-ij" :start 3) + "abCd efgh-ij") + +(my-assert + (string-downcase "abCD efGh-ij" :end 3) + "abcD efGh-ij") + +(my-assert + (string-downcase "abCD efGh-ij" :start 3 :end 3) + "abCD efGh-ij") + +(my-assert + (string-downcase "abCD efGh-ij" :start 1 :end 6) + "abcd efGh-ij") + +(my-assert + (string-downcase "abCD efGh-ij" :start 6 :end 1) + error) + +(my-assert + (string-capitalize "abcd def g hi") + "Abcd Def G Hi") + +(my-assert + (string-capitalize "abCd dEf G hi") + "Abcd Def G Hi") + +(my-assert + (string-capitalize "Abcd Def G Hi") + "Abcd Def G Hi") + +(my-assert + (string-capitalize "abcd def g hi" :start 6) + "abcd dEf G Hi") + +(my-assert + (string-capitalize "abcd def g hi" :end 6) + "Abcd Def g hi") + +(my-assert + (string-capitalize "abcd def g hi" :start 2 :end 10) + "abCd Def G hi") + +(my-assert + (string-capitalize "abcd def g hi" :start 10 :end 2) + error) + +(my-assert + (string-capitalize "don't") + "Don'T") + +(my-assert + (string-capitalize "DON'T") + "Don'T") + +(my-assert + (string-capitalize "34a 5BC") + "34a 5bc") + +(my-assert + (string 1) + error) + +(my-assert + (string (quote a)) + "A") + +(my-assert + (string #\a) + "a") + +(my-assert + (string "abc") + "abc") + +(my-assert + (nstring-upcase + (copy-seq "abCD efGh-ij")) + "ABCD EFGH-IJ") + +(my-assert + (nstring-upcase + (copy-seq "abCD efGh-ij") + :start 5) + "abCD EFGH-IJ") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ij") + :end 5) + "ABCD efGh-ij") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ij") + :start6 :end 1) + error) + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ij") + :start 3 :end 3) + "abCD efGh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCD efGh-ij")) + "abcd efgh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCD efGh-ij") + :start 3) + "abCd efgh-ij") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ij") + :start 1 :end 6) + "aBCD EfGh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCD efGh-ij") + :end 3) + "abcD efGh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCd efGh-ij") + :start 3 :end 3) + "abCd efGh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCd efGh-ij") + :start 1 :end 6) + "abcd efGh-ij") + +(my-assert + (nstring-downcase (copy-seq "abCD efGh-ij") + :start 6 :end 1) + error) + +(my-assert + (nstring-downcase (copy-seq "abCD efGh-ij") + :start nil :end nil) + #+(or xcl akcl) "abcd efgh-ij" + #-(or xcl akcl) error) + +(my-assert + (nstring-upcase (copy-seq "abDC efGh-oj")) + "ABDC EFGH-OJ") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ij") + :start 1 :end 6) + "aBCD EfGh-ij") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-fg") + :start 1 :end 6) + "aBCD EfGh-fg") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ef") + :start 3 :end 3) + "abCD efGh-ef") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ef") + :start 3 :end 3) + "abCD efGh-ef") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ef") + :start 3 :end 3) + "abCD efGh-ef") + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ef") + :start 3 :end 1) + error) + +(my-assert + (nstring-upcase (copy-seq "abCD efGh-ef") + :start nil :end nil) + #+(or xcl akcl) "ABCD EFGH-EF" + #-(or xcl akcl) error) + +(my-assert + (nstring-downcase (copy-seq "saBG efGh-ef")) + "sabg efgh-ef") + +(my-assert + (nstring-downcase (copy-seq "dfGV efGh-ef") + :start 1 :end 6) + "dfgv efGh-ef") + +(my-assert + (nstring-downcase (copy-seq "fgCD efGf-ef") + :start 1 :end 3) + "fgcD efGf-ef") + +(my-assert + (nstring-downcase (copy-seq "dfCF edFg-fg") + :start nil :end nil) + #+(or xcl akcl) "dfcf edfg-fg" + #-(or xcl akcl) error) + +(my-assert + (nstring-downcase (copy-seq "fgHG edgf-fg") + :start 5 :end 1) + error) + +(my-assert + (nstring-downcase (copy-seq "scDF edFG-ef") + :start 1) + "scdf edfg-ef") + +(my-assert + (nstring-downcase (copy-seq "fgHG edFG-ef") + :end 4) + "fghg edFG-ef") + +(my-assert + (nstring-capitalize (copy-seq "fg hgf fgh")) + "Fg Hgf Fgh") + +(my-assert + (let ((x (copy-seq "ABCDEF"))) + (nstring-downcase x) + x) + "abcdef") + diff --git a/src/ansi-tests/symbol10.lisp b/src/ansi-tests/symbol10.lisp new file mode 100644 index 000000000..f56f1ae30 --- /dev/null +++ b/src/ansi-tests/symbol10.lisp @@ -0,0 +1,706 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (progn (in-package :cl-user) nil) + nil + "in-package expects a 'string designator' +this is or a character, a symbol or a string.") +;; test der neuen valuezelle + +;;; 1. ungebundenes symbol + + +(my-assert + (defun testvar (var) + (list (boundp var) ; gebunden + (if (boundp var) + (symbol-value var) + nil) ; wert/nil + (constantp var) ; konstante + #+xcl + (eq (sys::%p-get-cdr var 0) + sys::%cdr-specsym) ; specvar + #+clisp + (and (sys::special-variable-p var) + (not (constantp var))) ; specvar + #+allegro + (and (not (constantp var)) + (eval `(let ((,var (list nil))) + (and (boundp ',var) + (eq (symbol-value ',var) + ,var))))) + #+cmu + (eq (ext:info variable kind var) + ':special);; like clisp + #+ecls + (si::specialp var) + #+sbcl + (eq (sb-int::info variable kind var) + ':special);; like clisp + (and (fboundp var) t) ; funktion. eigenschaft + (and (fboundp var) (macro-function var) t) ; macro? + (and (fboundp var) + (special-operator-p var) + t) ; spezialform? + #-clisp + (and (symbol-plist var) t) ; p-liste? + #+clisp + (and (or (get var 'i1) + (get var 'i2) + (get var 'i3)) + t) ; p-liste? + (get var 'i1) ; i1 + (get var 'i2) ; i2 + (get var 'i3) ; i3 + ) ) + testvar) + +(my-assert + (defun clrvar (var) + #+xcl + (subr 84 ;sys::%p-set-cdr-content + var 0 (sys::%p-get-content 'sys::%void-value 0) 0) + #-xcl + (progn (makunbound var) (fmakunbound var) + (setf (symbol-plist var) '())) + #+allegro + (setf (excl::symbol-bit var 'excl::.globally-special.) nil) + #+cmu + (setf (ext:info variable kind var) ':global) + #+sbcl + (setf (sb-int::info variable kind var) ':global) + var) + clrvar) + +#+(or xcl clisp allegro cmu sbcl) +(my-assert + (progn (setf (symbol-function 'setf-get) + (symbol-function #+xcl 'sys::setf-get + #+clisp 'sys::%put + #+allegro 'excl::.inv-get + #+(or cmu sbcl) 'cl::%put)) t) + t) + +;;; begin breitentest + +(my-assert + (clrvar 'v1) + v1) + +;;;; value - umbinden - macro - umbinden - props - umbinden + +;;; value + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (setq v1 'val) + val) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val nil nil nil nil nil nil nil nil nil)) + +;;; umbinden + +(my-assert + (makunbound 'v1) + v1) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (setq v1 'val2) + val2) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val2 nil nil nil nil nil nil nil nil nil)) + +;;; macro + +(my-assert + (defmacro v1 (x) (list 'quote x)) + v1) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val2 nil nil t t nil nil nil nil nil)) + +;;; umbinden + +(my-assert + (fmakunbound 'v1) + v1) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val2 nil nil nil nil nil nil nil nil nil)) + +(my-assert + (defmacro v1 (x) (list 'quote (list x x))) + v1) + +(my-assert + (v1 33) + (33 33)) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val2 nil nil t t nil nil nil nil nil)) + +(my-assert + (makunbound 'v1) + v1) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t t nil nil nil nil nil)) + +(my-assert + (setq v1 'val3) + val3) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val3 nil nil t t nil nil nil nil nil)) + +;;; props + +(my-assert + (setf-get 'v1 'i1 11) + 11) + +(my-assert + (setf-get 'v1 'i2 22) + 22) + +(my-assert + (setf-get 'v1 'i3 33) + 33) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val3 nil nil t t nil t 11 22 33)) + +;;; umbinden + +(my-assert + (not (null (remprop 'v1 'i2))) + t) +(my-assert + (not (null (remprop 'v1 'i1))) + t) +(my-assert + (not (null (remprop 'v1 'i3))) + t) +(my-assert + (fmakunbound 'v1) + v1) +(my-assert + (makunbound 'v1) + v1) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (setf-get 'v1 'i1 99) + 99) +(my-assert + (defmacro v1 (x) (list 'quote (list x x x))) + v1) +(my-assert + (v1 a) + (a a a)) +(my-assert + (setq v1 'val4) + val4) + +(my-assert + (testvar 'v1) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t val4 nil nil t t nil t 99 nil nil)) + +;;; --- ende test1 ----- + +(my-assert + (clrvar 'v2) + v2) + +;;; specvar - props - rebind - function + +(my-assert + (defvar v2 'v2a) + v2) + +(my-assert + (testvar 'v2) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t v2a nil t nil nil nil nil nil nil nil)) + +(my-assert + (setf-get 'v2 'i3 33) + 33) +(my-assert + (setf-get 'v2 'i2 22) + 22) +(my-assert + (setf-get 'v2 'i1 11) + 11) + +(my-assert + (testvar 'v2) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t v2a nil t nil nil nil t 11 22 33)) + +;;; rebind + +(my-assert + (makunbound 'v2) + v2) +(my-assert + (not (null (remprop 'v2 'i1))) + t) +(my-assert + (not (null (remprop 'v2 'i2))) + t) +(my-assert + (not (null (remprop 'v2 'i3))) + t) + +(my-assert + (testvar 'v2) + ;; geb val konst svar func mac spec plist i1 i2 i3 + #+xcl + (nil nil nil nil nil nil nil nil nil nil nil) + #-xcl + (nil nil nil t nil nil nil nil nil nil nil)) + +(my-assert + (defvar v2 'v2b) + v2) +(my-assert + (setf-get 'v2 'i1 111) + 111) +(my-assert + (setf-get 'v2 'i2 222) + 222) +(my-assert + (setf-get 'v2 'i3 333) + 333) + +(my-assert + (testvar 'v2) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t v2b nil t nil nil nil t 111 222 333)) + +;;; function + +(my-assert + (defun v2 (x) (list x x)) + v2) +(my-assert + (v2 44) + (44 44)) + +(my-assert + (testvar 'v2) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t v2b nil t t nil nil t 111 222 333 )) + + +(my-assert + (clrvar 'v3) + v3) + +;;;;; function - con - rebind - prop + +;;; function + +(my-assert + (defun v3 (x y) (list x y)) + v3) + +(my-assert + (testvar 'v3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t nil nil nil nil nil nil)) + +;;; constant + +(my-assert + (defconstant v3 99) + v3) + +(my-assert + v3 + 99) +(my-assert + (v3 'a 'b) + (a b)) + +(my-assert + (testvar 'v3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 99 t nil t nil nil nil nil nil nil)) + +;;; rebind + +(my-assert + (makunbound 'v3) + #+(or xcl allegro cmu sbcl) v3 + #+(or clisp ecls) error) + +(my-assert + (fmakunbound 'v3) + v3) + +#+xcl +(my-assert + (testvar 'v3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (defconstant v3 999) + v3) + +(my-assert + (defun v3 (x) (list x x)) + v3) + +(my-assert + (v3 'c) + (c c)) + +(my-assert + v3 + 999) + +(my-assert + (testvar 'v3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 999 t nil t nil nil nil nil nil nil)) + +;;;defparameter + +(my-assert + (defparameter var33) + error) + +(my-assert + (defparameter var3 99) + var3) + +(my-assert + var3 + 99) + +(my-assert + (testvar 'var3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 99 nil t nil nil nil nil nil nil nil)) + +;;; rebind + +(my-assert + (makunbound 'var3) + var3) + +(my-assert + (testvar 'var3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + #+xcl + (nil nil nil nil nil nil nil nil nil nil nil) + #-xcl + (nil nil nil t nil nil nil nil nil nil nil)) + +;;; props + +(my-assert + (setf-get 'v3 'i2 222) + 222) + +(my-assert + (setf-get 'v3 'i1 111) + 111) + +(my-assert + (testvar 'v3) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 999 t nil t nil nil t 111 222 nil)) + + +(my-assert + (clrvar 'v4) + v4) + +;;;; function - rebind - prop - rebind - specvar + +(my-assert + (defun v4 (x) x) + v4) + +(my-assert + (v4 55) + 55) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t nil nil nil nil nil nil)) + +;;; rebind + +(my-assert + (fmakunbound 'v4) + v4) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (defun v4 (x) (list x)) + v4) + +(my-assert + (v4 88) + (88)) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t nil nil nil nil nil nil)) + +(my-assert + (setf-get 'v4 'i1 11) + 11) + +(my-assert + (setf-get 'v4 'i2 22) + 22) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t nil nil t 11 22 nil)) + +;;; rebind + +(my-assert + (fmakunbound 'v4) + v4) +(my-assert + (not (null (remprop 'v4 'i1))) + t) +(my-assert + (not (null (remprop 'v4 'i2))) + t) +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (defun v4 (x) (list x x x)) + v4) + +(my-assert + (v4 44) + (44 44 44)) + +(my-assert + (setf-get 'v4 'i2 222) + 222) + +(my-assert + (setf-get 'v4 'i3 333) + 333) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t nil nil t nil 222 333)) + +(my-assert + (defvar v4 'v4-value) + v4) + +(my-assert + (testvar 'v4) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t v4-value nil t t nil nil t nil 222 333)) + +(my-assert + (clrvar 'v5) + v5) + +;;;;; prop - rebind - con - rebind - fun + +(my-assert + (setf-get 'v5 'i1 1) + 1) +(my-assert + (setf-get 'v5 'i2 2) + 2) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil t 1 2 nil)) + +;;; rebind + +(my-assert + (not (null (remprop 'v5 'i1))) + t) +(my-assert + (not (null (remprop 'v5 'i2))) + t) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +(my-assert + (setf-get 'v5 'i1 11) + 11) +(my-assert + (setf-get 'v5 'i2 22) + 22) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil t 11 22 nil)) + +;;; con + +(my-assert + (defconstant v5 '123) + v5) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 123 t nil nil nil nil t 11 22 nil)) + +;;; rebind + +(my-assert + (makunbound 'v5) + #+(or xcl allegro cmu sbcl) v5 + #+(or clisp ecls) error) + +(my-assert + (not (null (remprop 'v5 'i2))) + t) + +(my-assert + (not (null (remprop 'v5 'i1))) + t) + +#+xcl +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil nil nil nil nil)) + +;;; das ging schief !! + +(my-assert + (defconstant v5 321) + v5) + +(my-assert + (setf-get 'v5 'i3 333) + 333) + +(my-assert + (setf-get 'v5 'i2 222) + 222) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 321 t nil nil nil nil t nil 222 333)) + +(my-assert + (defun v5 (x) x) + v5) + +(my-assert + (v5 666) + 666) + +(my-assert + (testvar 'v5) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 321 t nil t nil nil t nil 222 333)) + +(my-assert + (clrvar 'v6) + v6) + +;;;;; prop mac con + +(my-assert + (setf-get 'v6 'i1 1) + 1) + +(my-assert + (setf-get 'v6 'i3 3) + 3) + +(my-assert + (testvar 'v6) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil nil nil nil t 1 nil 3)) + +(my-assert + (defmacro v6 (x) (list 'quote x)) + v6) + +(my-assert + (v6 a) + a) + +(my-assert + (testvar 'v6) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (nil nil nil nil t t nil t 1 nil 3)) + +(my-assert + (defconstant v6 234) + v6) + +(my-assert + (testvar 'v6) + ;; geb val konst svar func mac spec plist i1 i2 i3 + (t 234 t nil t t nil t 1 nil 3)) + + +;; aufraeumen +(mapc #'unintern '(v1 v2 v3 v4 v5 v6)) + diff --git a/src/ansi-tests/symbols.lisp b/src/ansi-tests/symbols.lisp new file mode 100644 index 000000000..b22e317d7 --- /dev/null +++ b/src/ansi-tests/symbols.lisp @@ -0,0 +1,21 @@ +;;; based on v1.2 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (symbol-name (quote xyz)) + "XYZ") + +(my-assert + (let ((*gensym-counter* 32)) + (gensym) + (prin1-to-string (gensym "FOO-"))) + "#:FOO-33") + +(my-assert + (let ((*gensym-counter* 32)) + (gensym) + (prin1-to-string (gensym "garbage-"))) + #+xcl "#:|garbage|-33" + #+(or clisp akcl allegro cmu sbcl ecls) "#:|garbage-33|" + #-(or xcl clisp akcl allegro cmu sbcl ecls) UNKNOWN) + diff --git a/src/ansi-tests/symboltest.lisp b/src/ansi-tests/symboltest.lisp new file mode 100644 index 000000000..d128dc5f5 --- /dev/null +++ b/src/ansi-tests/symboltest.lisp @@ -0,0 +1,509 @@ +;;; Peter Van Eynde, 1 March 2000 -*- mode: lisp -*- + +(in-package :cl-user) + + +(defvar *the-cl-package* (find-package :common-lisp)) + +(my-assert + (packagep *the-cl-package*) + t) + +(my-assert + (package-name *the-cl-package*) + "COMMON-LISP") + +(my-assert + (not + (member "CL" + (package-nicknames *the-cl-package*) + :test #'string-equal)) + NIL) + + +(defvar *allowed-exported-symbols* + '("&allow-other-keys" "*print-miser-width*" + "&aux" "*print-pprint-dispatch*" + "&body" "*print-pretty*" + "&environment" "*print-radix*" + "&key" "*print-readably*" + "&optional" "*print-right-margin*" + "&rest" "*query-io*" + "&whole" "*random-state*" + "*" "*read-base*" + "**" "*read-default-float-format*" + "***" "*read-eval*" + "*break-on-signals*" "*read-suppress*" + "*compile-file-pathname*" "*readtable*" + "*compile-file-truename*" "*standard-input*" + "*compile-print*" "*standard-output*" + "*compile-verbose*" "*terminal-io*" + "*debug-io*" "*trace-output*" + "*debugger-hook*" "+" + "*default-pathname-defaults*" "++" + "*error-output*" "+++" + "*features*" "-" + "*gensym-counter*" "/" + "*load-pathname*" "//" + "*load-print*" "///" + "*load-truename*" "/=" + "*load-verbose*" "1+" + "*macroexpand-hook*" "1-" + "*modules*" "<" + "*package*" "<=" + "*print-array*" "=" + "*print-base*" ">" + "*print-case*" ">=" + "*print-circle*" "abort" + "*print-escape*" "abs" + "*print-gensym*" "acons" + "*print-length*" "acos" + "*print-level*" "acosh" + "*print-lines*" "add-method" + "adjoin" "atom" "boundp" + "adjust-array" "base-char" "break" + "adjustable-array-p" "base-string" "broadcast-stream" + "allocate-instance" "bignum" "broadcast-stream-streams" + "alpha-char-p" "bit" "built-in-class" + "alphanumericp" "bit-and" "butlast" + "and" "bit-andc1" "byte" + "append" "bit-andc2" "byte-position" + "apply" "bit-eqv" "byte-size" + "apropos" "bit-ior" "caaaar" + "apropos-list" "bit-nand" "caaadr" + "aref" "bit-nor" "caaar" + "arithmetic-error" "bit-not" "caadar" + "arithmetic-error-operands" "bit-orc1" "caaddr" + "arithmetic-error-operation" "bit-orc2" "caadr" + "array" "bit-vector" "caar" + "array-dimension" "bit-vector-p" "cadaar" + "array-dimension-limit" "bit-xor" "cadadr" + "array-dimensions" "block" "cadar" + "array-displacement" "boole" "caddar" + "array-element-type" "boole-1" "cadddr" + "array-has-fill-pointer-p" "boole-2" "caddr" + "array-in-bounds-p" "boole-and" "cadr" + "array-rank" "boole-andc1" "call-arguments-limit" + "array-rank-limit" "boole-andc2" "call-method" + "array-row-major-index" "boole-c1" "call-next-method" + "array-total-size" "boole-c2" "car" + "array-total-size-limit" "boole-clr" "case" + "arrayp" "boole-eqv" "catch" + "ash" "boole-ior" "ccase" + "asin" "boole-nand" "cdaaar" + "asinh" "boole-nor" "cdaadr" + "assert" "boole-orc1" "cdaar" + "assoc" "boole-orc2" "cdadar" + "assoc-if" "boole-set" "cdaddr" + "assoc-if-not" "boole-xor" "cdadr" + "atan" "boolean" "cdar" + "atanh" "both-case-p" "cddaar" + "cddadr" "clear-input" "copy-tree" + "cddar" "clear-output" "cos" + "cdddar" "close" "cosh" + "cddddr" "clrhash" "count" + "cdddr" "code-char" "count-if" + "cddr" "coerce" "count-if-not" + "cdr" "compilation-speed" "ctypecase" + "ceiling" "compile" "debug" + "cell-error" "compile-file" "decf" + "cell-error-name" "compile-file-pathname" "declaim" + "cerror" "compiled-function" "declaration" + "change-class" "compiled-function-p" "declare" + "char" "compiler-macro" "decode-float" + "char-code" "compiler-macro-function" "decode-universal-time" + "char-code-limit" "complement" "defclass" + "char-downcase" "complex" "defconstant" + "char-equal" "complexp" "defgeneric" + "char-greaterp" "compute-applicable-methods" "define-compiler-macro" + "char-int" "compute-restarts" "define-condition" + "char-lessp" "concatenate" "define-method-combination" + "char-name" "concatenated-stream" "define-modify-macro" + "char-not-equal" "concatenated-stream-streams" "define-setf-expander" + "char-not-greaterp" "cond" "define-symbol-macro" + "char-not-lessp" "condition" "defmacro" + "char-upcase" "conjugate" "defmethod" + "char/=" "cons" "defpackage" + "char<" "consp" "defparameter" + "char<=" "constantly" "defsetf" + "char=" "constantp" "defstruct" + "char>" "continue" "deftype" + "char>=" "control-error" "defun" + "character" "copy-alist" "defvar" + "characterp" "copy-list" "delete" + "check-type" "copy-pprint-dispatch" "delete-duplicates" + "cis" "copy-readtable" "delete-file" + "class" "copy-seq" "delete-if" + "class-name" "copy-structure" "delete-if-not" + "class-of" "copy-symbol" "delete-package" + "denominator" "eq" + "deposit-field" "eql" + "describe" "equal" + "describe-object" "equalp" + "destructuring-bind" "error" + "digit-char" "etypecase" + "digit-char-p" "eval" + "directory" "eval-when" + "directory-namestring" "evenp" + "disassemble" "every" + "division-by-zero" "exp" + "do" "export" + "do*" "expt" + "do-all-symbols" "extended-char" + "do-external-symbols" "fboundp" + "do-symbols" "fceiling" + "documentation" "fdefinition" + "dolist" "ffloor" + "dotimes" "fifth" + "double-float" "file-author" + "double-float-epsilon" "file-error" + "double-float-negative-epsilon" "file-error-pathname" + "dpb" "file-length" + "dribble" "file-namestring" + "dynamic-extent" "file-position" + "ecase" "file-stream" + "echo-stream" "file-string-length" + "echo-stream-input-stream" "file-write-date" + "echo-stream-output-stream" "fill" + "ed" "fill-pointer" + "eighth" "find" + "elt" "find-all-symbols" + "encode-universal-time" "find-class" + "end-of-file" "find-if" + "endp" "find-if-not" + "enough-namestring" "find-method" + "ensure-directories-exist" "find-package" + "ensure-generic-function" "find-restart" + "find-symbol" "get-internal-run-time" + "finish-output" "get-macro-character" + "first" "get-output-stream-string" + "fixnum" "get-properties" + "flet" "get-setf-expansion" + "float" "get-universal-time" + "float-digits" "getf" + "float-precision" "gethash" + "float-radix" "go" + "float-sign" "graphic-char-p" + "floating-point-inexact" "handler-bind" + "floating-point-invalid-operation" "handler-case" + "floating-point-overflow" "hash-table" + "floating-point-underflow" "hash-table-count" + "floatp" "hash-table-p" + "floor" "hash-table-rehash-size" + "fmakunbound" "hash-table-rehash-threshold" + "force-output" "hash-table-size" + "format" "hash-table-test" + "formatter" "host-namestring" + "fourth" "identity" + "fresh-line" "if" + "fround" "ignorable" + "ftruncate" "ignore" + "ftype" "ignore-errors" + "funcall" "imagpart" + "function" "import" + "function-keywords" "in-package" + "function-lambda-expression" "incf" + "functionp" "initialize-instance" + "gcd" "inline" + "generic-function" "input-stream-p" + "gensym" "inspect" + "gentemp" "integer" + "get" "integer-decode-float" + "get-decoded-time" "integer-length" + "get-dispatch-macro-character" "integerp" + "get-internal-real-time" "interactive-stream-p" + "intern" "lisp-implementation-type" + "internal-time-units-per-second" "lisp-implementation-version" + "intersection" "list" + "invalid-method-error" "list*" + "invoke-debugger" "list-all-packages" + "invoke-restart" "list-length" + "invoke-restart-interactively" "listen" + "isqrt" "listp" + "keyword" "load" + "keywordp" "load-logical-pathname-translations" + "labels" "load-time-value" + "lambda" "locally" + "lambda-list-keywords" "log" + "lambda-parameters-limit" "logand" + "last" "logandc1" + "lcm" "logandc2" + "ldb" "logbitp" + "ldb-test" "logcount" + "ldiff" "logeqv" + "least-negative-double-float" "logical-pathname" + "least-negative-long-float" "logical-pathname-translations" + "least-negative-normalized-double-float" "logior" + "least-negative-normalized-long-float" "lognand" + "least-negative-normalized-short-float" "lognor" + "least-negative-normalized-single-float" "lognot" + "least-negative-short-float" "logorc1" + "least-negative-single-float" "logorc2" + "least-positive-double-float" "logtest" + "least-positive-long-float" "logxor" + "least-positive-normalized-double-float" "long-float" + "least-positive-normalized-long-float" "long-float-epsilon" + "least-positive-normalized-short-float" "long-float-negative-epsilon" + "least-positive-normalized-single-float" "long-site-name" + "least-positive-short-float" "loop" + "least-positive-single-float" "loop-finish" + "length" "lower-case-p" + "let" "machine-instance" + "let*" "machine-type" + "machine-version" "mask-field" + "macro-function" "max" + "macroexpand" "member" + "macroexpand-1" "member-if" + "macrolet" "member-if-not" + "make-array" "merge" + "make-broadcast-stream" "merge-pathnames" + "make-concatenated-stream" "method" + "make-condition" "method-combination" + "make-dispatch-macro-character" "method-combination-error" + "make-echo-stream" "method-qualifiers" + "make-hash-table" "min" + "make-instance" "minusp" + "make-instances-obsolete" "mismatch" + "make-list" "mod" + "make-load-form" "most-negative-double-float" + "make-load-form-saving-slots" "most-negative-fixnum" + "make-method" "most-negative-long-float" + "make-package" "most-negative-short-float" + "make-pathname" "most-negative-single-float" + "make-random-state" "most-positive-double-float" + "make-sequence" "most-positive-fixnum" + "make-string" "most-positive-long-float" + "make-string-input-stream" "most-positive-short-float" + "make-string-output-stream" "most-positive-single-float" + "make-symbol" "muffle-warning" + "make-synonym-stream" "multiple-value-bind" + "make-two-way-stream" "multiple-value-call" + "makunbound" "multiple-value-list" + "map" "multiple-value-prog1" + "map-into" "multiple-value-setq" + "mapc" "multiple-values-limit" + "mapcan" "name-char" + "mapcar" "namestring" + "mapcon" "nbutlast" + "maphash" "nconc" + "mapl" "next-method-p" + "maplist" "nil" + "nintersection" "package-error" + "ninth" "package-error-package" + "no-applicable-method" "package-name" + "no-next-method" "package-nicknames" + "not" "package-shadowing-symbols" + "notany" "package-use-list" + "notevery" "package-used-by-list" + "notinline" "packagep" + "nreconc" "pairlis" + "nreverse" "parse-error" + "nset-difference" "parse-integer" + "nset-exclusive-or" "parse-namestring" + "nstring-capitalize" "pathname" + "nstring-downcase" "pathname-device" + "nstring-upcase" "pathname-directory" + "nsublis" "pathname-host" + "nsubst" "pathname-match-p" + "nsubst-if" "pathname-name" + "nsubst-if-not" "pathname-type" + "nsubstitute" "pathname-version" + "nsubstitute-if" "pathnamep" + "nsubstitute-if-not" "peek-char" + "nth" "phase" + "nth-value" "pi" + "nthcdr" "plusp" + "null" "pop" + "number" "position" + "numberp" "position-if" + "numerator" "position-if-not" + "nunion" "pprint" + "oddp" "pprint-dispatch" + "open" "pprint-exit-if-list-exhausted" + "open-stream-p" "pprint-fill" + "optimize" "pprint-indent" + "or" "pprint-linear" + "otherwise" "pprint-logical-block" + "output-stream-p" "pprint-newline" + "package" "pprint-pop" + "pprint-tab" "read-char" + "pprint-tabular" "read-char-no-hang" + "prin1" "read-delimited-list" + "prin1-to-string" "read-from-string" + "princ" "read-line" + "princ-to-string" "read-preserving-whitespace" + "print" "read-sequence" + "print-not-readable" "reader-error" + "print-not-readable-object" "readtable" + "print-object" "readtable-case" + "print-unreadable-object" "readtablep" + "probe-file" "real" + "proclaim" "realp" + "prog" "realpart" + "prog*" "reduce" + "prog1" "reinitialize-instance" + "prog2" "rem" + "progn" "remf" + "program-error" "remhash" + "progv" "remove" + "provide" "remove-duplicates" + "psetf" "remove-if" + "psetq" "remove-if-not" + "push" "remove-method" + "pushnew" "remprop" + "quote" "rename-file" + "random" "rename-package" + "random-state" "replace" + "random-state-p" "require" + "rassoc" "rest" + "rassoc-if" "restart" + "rassoc-if-not" "restart-bind" + "ratio" "restart-case" + "rational" "restart-name" + "rationalize" "return" + "rationalp" "return-from" + "read" "revappend" + "read-byte" "reverse" + "room" "simple-bit-vector" + "rotatef" "simple-bit-vector-p" + "round" "simple-condition" + "row-major-aref" "simple-condition-format-arguments" + "rplaca" "simple-condition-format-control" + "rplacd" "simple-error" + "safety" "simple-string" + "satisfies" "simple-string-p" + "sbit" "simple-type-error" + "scale-float" "simple-vector" + "schar" "simple-vector-p" + "search" "simple-warning" + "second" "sin" + "sequence" "single-float" + "serious-condition" "single-float-epsilon" + "set" "single-float-negative-epsilon" + "set-difference" "sinh" + "set-dispatch-macro-character" "sixth" + "set-exclusive-or" "sleep" + "set-macro-character" "slot-boundp" + "set-pprint-dispatch" "slot-exists-p" + "set-syntax-from-char" "slot-makunbound" + "setf" "slot-missing" + "setq" "slot-unbound" + "seventh" "slot-value" + "shadow" "software-type" + "shadowing-import" "software-version" + "shared-initialize" "some" + "shiftf" "sort" + "short-float" "space" + "short-float-epsilon" "special" + "short-float-negative-epsilon" "special-operator-p" + "short-site-name" "speed" + "signal" "sqrt" + "signed-byte" "stable-sort" + "signum" "standard" + "simple-array" "standard-char" + "simple-base-string" "standard-char-p" + "standard-class" "sublis" + "standard-generic-function" "subseq" + "standard-method" "subsetp" + "standard-object" "subst" + "step" "subst-if" + "storage-condition" "subst-if-not" + "store-value" "substitute" + "stream" "substitute-if" + "stream-element-type" "substitute-if-not" + "stream-error" "subtypep" + "stream-error-stream" "svref" + "stream-external-format" "sxhash" + "streamp" "symbol" + "string" "symbol-function" + "string-capitalize" "symbol-macrolet" + "string-downcase" "symbol-name" + "string-equal" "symbol-package" + "string-greaterp" "symbol-plist" + "string-left-trim" "symbol-value" + "string-lessp" "symbolp" + "string-not-equal" "synonym-stream" + "string-not-greaterp" "synonym-stream-symbol" + "string-not-lessp" "t" + "string-right-trim" "tagbody" + "string-stream" "tailp" + "string-trim" "tan" + "string-upcase" "tanh" + "string/=" "tenth" + "string<" "terpri" + "string<=" "the" + "string=" "third" + "string>" "throw" + "string>=" "time" + "stringp" "trace" + "structure" "translate-logical-pathname" + "structure-class" "translate-pathname" + "structure-object" "tree-equal" + "style-warning" "truename" + "truncate" "values-list" + "two-way-stream" "variable" + "two-way-stream-input-stream" "vector" + "two-way-stream-output-stream" "vector-pop" + "type" "vector-push" + "type-error" "vector-push-extend" + "type-error-datum" "vectorp" + "type-error-expected-type" "warn" + "type-of" "warning" + "typecase" "when" + "typep" "wild-pathname-p" + "unbound-slot" "with-accessors" + "unbound-slot-instance" "with-compilation-unit" + "unbound-variable" "with-condition-restarts" + "undefined-function" "with-hash-table-iterator" + "unexport" "with-input-from-string" + "unintern" "with-open-file" + "union" "with-open-stream" + "unless" "with-output-to-string" + "unread-char" "with-package-iterator" + "unsigned-byte" "with-simple-restart" + "untrace" "with-slots" + "unuse-package" "with-standard-io-syntax" + "unwind-protect" "write" + "update-instance-for-different-class" "write-byte" + "update-instance-for-redefined-class" "write-char" + "upgraded-array-element-type" "write-line" + "upgraded-complex-part-type" "write-sequence" + "upper-case-p" "write-string" + "use-package" "write-to-string" + "use-value" "y-or-n-p" + "user-homedir-pathname" "yes-or-no-p" + "values" "zerop")) + +;; test there aren't any symbols too much +(my-assert + (set-difference + (loop for symbol being + the external-symbol + of *the-cl-package* + collect symbol) + *allowed-exported-symbols* + :test #'string-equal) + nil + "This is the list of symbols that are exported but should not be exported +from the :cl package") + +;; test there aren't any symbols missing +(my-assert + (set-difference + *allowed-exported-symbols* + (loop for symbol being + the external-symbol + of *the-cl-package* + collect symbol) + :test #'string-equal) + nil + "This is the list of symbols that are missing or not exported +from the :cl package") + + +(makunbound '*allowed-exported-symbols*) +(unintern '*allowed-exported-symbols*) + + + + diff --git a/src/ansi-tests/tests.lisp b/src/ansi-tests/tests.lisp new file mode 100644 index 000000000..bf8485a38 --- /dev/null +++ b/src/ansi-tests/tests.lisp @@ -0,0 +1,228 @@ +;; Test-Suiten ablaufen lassen: -*- mode: lisp -*- +(in-package :user) + +(declaim (optimize (speed 0) + (safety 3) + (debug 3))) + +(defmacro with-ignored-errors (&rest forms) + "This macro will evaluate the forms and return +the returnvalues or the type of the condition used." + (let ((tag (gensym))) + `(block ,tag + (handler-bind + ((serious-condition + #'(lambda (condition) + (return-from ,tag + (values :ERROR + condition))))) + ,@forms)))) + +(defvar *log* nil) +(defvar *output-generated* nil) +(defvar *lisp-type* + #+ecls "ECLS" + #+CLISP "CLISP" + #+AKCL "AKCL" + #+CMU "CMUCL" + #+sbcl "SBCL") + +(defun check-and-puke (mode form result my-result condition why) + (flet ((safe-format (stream string &rest args) + (unless (ignore-errors + (progn + (apply #'format stream string args) + t)) + (format stream "~&~%format of ~S failed!" + string)))) + (cond + ((eql result my-result) + (safe-format t "~%EQL-OK: ~S" my-result)) + ((equal result my-result) + (safe-format t "~%EQUAL-OK: ~S" my-result)) + ((equalp result my-result) + (safe-format t "~%EQUALP-OK: ~S" my-result)) + ((eq my-result :ERROR) + (cond + ((ignore-errors + (typep condition result)) + (safe-format t "~%TYPEP-OK, is of the expected error :~S" + result)) + (t + (safe-format + t + "~&~%ERROR!! Got an error ~S (~A) I expected a instance of ~S~%" + condition condition + result) + (safe-format + t + "~%Form: ~S~%Should be an error of type: ~S~%~A: ~S (~A)~%Why: ~S~%" + form result *lisp-type* + condition condition + why) + (setf *output-generated* t) + (safe-format + *log* + "~&~%~A Form: ~S~%Should be an error of type: ~S~%~A: ~S (~A) ~%Why: ~S~%" + mode form result *lisp-type* + condition condition + why)))) + (t + (safe-format t + "~&~%ERROR!! Got ~S solution ~S expected!" + my-result result) + (safe-format t + "~%~A Form: ~S~%Should be: ~S~%~A: ~S~%Why: ~S~%" + mode form result *lisp-type* + my-result why) + (setf *output-generated* t) + (safe-format *log* + "~&~%~A Form: ~S~%Should be: ~S~%~A: ~S~%Why : ~S~%" + mode form result *lisp-type* + my-result why))))) + +(defmacro my-assert (form result &optional (why "")) + `(progn + (format t "~&~%testing : ~S~%" + ',form) + + ;;; first we check if it work in interpreted mode + + (multiple-value-bind (my-result condition) + (with-ignored-errors + (eval ',form)) + (check-and-puke "interpreted" + ',form ',result + my-result condition + ,why)) + + (force-output) + + ;;; now we try to compile... + #+nil ; HACK + (multiple-value-bind (my-result condition) + (with-ignored-errors + (multiple-value-bind (function warnings-p failure-p) + (compile nil + #'(lambda () + ,form)) + (format t "~&compiled ~S ~S ~S" + function warnings-p failure-p) + + (multiple-value-bind (my-result condition) + (with-ignored-errors + (funcall function)) + (check-and-puke "compiled" + ',form ',result + my-result condition + ,why)))) + (when (eq my-result :error) + (check-and-puke "while compiling" + ',form ',result + my-result condition + ,why))))) + +(defun run-test (testname &optional (source-path nil)) + (let ((*package* *package*) + (*print-pretty* nil) + (*print-circle* nil) + ;; to make the system quiet: + #+(or cmu sbcl) + (*gc-verbose* nil) + #+(or cmu sbcl) + (*compile-verbose* nil) + #+(or cmu sbcl) + (*compile-print* nil) + #+(or cmu sbcl) + (*compile-progress* nil) + #+(or cmu sbcl) + (*TOP-LEVEL-AUTO-DECLARE* nil) + (err-file (merge-pathnames testname "foo.erg")) + (source-file (merge-pathnames testname "foo.lisp"))) + (when source-path + (setq source-file (merge-pathnames source-file source-path))) + (with-open-file (*log* err-file :direction :output) + (setf *output-generated* nil) + (load source-file) + (force-output *log*)) + (unless *output-generated* + (delete-file err-file))) + (values)) + +(defun run-all-tests (&optional source-path) + (mapc #'(lambda (x) (print x) (run-test x source-path)) + '( + "symboltest" + #-akcl "alltest" + "array" + "backquot" + #-akcl "characters" + #+(or CLISP ALLEGRO CMU SBCL)"clos" + #-ECLS + "cmucl-bugs" + #+(or CLISP ALLEGRO CMU SBCL ECLS) "conditions" + "eval20" + #-ecls + "excepsit" + "format" + #+xcl "hash" + "hashlong" + "iofkts" + "lambda" + "lists151" + "lists152" + "lists153" + "lists154" + "lists155" + "lists156" + #+(or CLISP ALLEGRO CMU SBCL) "loop" + "macro8" + "map" + #+(or CLISP ALLEGRO CMU SBCL) "mop" + "new-bugs" + #-(or cmu sbcl ecls) "number" + #+clisp "number2" + #+(or XCL CLISP) "path" + #+xcl "readtable" + "section10" + "section11" + "section12" + "section13" + "section14" + "section15" + "section16" + "section17" + #-ecls + "section18-errors" + "section18" + "section19" + "section2" + "section20" + "section21" + "section22" + "section3" + "section4" + "section5" + "section6" + "section7" + "section8" + "section9" + "setf" + "steele7" + #-allegro "streams" + "streamslong" + "strings" + #-akcl "symbol10" + "symbols" + "type" + #+(or sbcl cmu) + "unix-tests" + )) + t) + +;(run-test "unix-tests") +;(run-test "steele7") +;(quit) +;(run-all-tests) +;(format t "~%~%alles ok...~%") +;(quit) diff --git a/src/ansi-tests/type.lisp b/src/ansi-tests/type.lisp new file mode 100644 index 000000000..11bcf579a --- /dev/null +++ b/src/ansi-tests/type.lisp @@ -0,0 +1,516 @@ +;;; based on v1.3 -*- mode: lisp -*- +(in-package :cl-user) + +(my-assert + (typep (quote a) (quote symbol)) + t) + +(my-assert + (typep (quote nil) (quote symbol)) + t) + +(my-assert + (typep (quote (nil)) (quote symbol)) + nil) + +(my-assert + (typep 3 (quote integer)) + t) + +(my-assert + (typep 3 (quote (integer 0 4))) + t) + +(my-assert + (typep 3 (quote (integer 0 3))) + t) + +(my-assert + (typep 3 (quote (integer 0 2))) + nil) + +(my-assert + (typep 3 (quote (float 0.0 2.0))) + nil) + +(my-assert + (typep 3 (quote (float 0.0 2.0))) + nil) + +(my-assert + (typep 3 (quote (float 0.0 4.0))) + nil) + +(my-assert + (typep 3.2 (quote (float 0.0 4.0))) + t) + +(my-assert + (typep 3.2 (quote (float 0.0 3.2))) + t) + +(my-assert + (typep 3.2 (quote (float 0.0 (3.2)))) + nil) + +(my-assert + (typep 3.2 (quote (short-float 0.0s0 3.2s0))) + #+(or allegro cmu sbcl) t + #-(or allegro cmu sbcl) nil) + +(my-assert + (typep 3.2 (quote (single-float 0.0f0 3.2f0))) + t) + +(my-assert + (typep 3.2 (quote (double-float 0.0d0 3.2d0))) + nil) + +(my-assert + (typep 3.2 (quote (double-float 0.0d0 3.2d0))) + nil) + +(my-assert + (typep 3.2 (quote (double-float 0.0d0 3.2d0))) + nil) + +(my-assert + (typep 3.2s0 (quote (double-float 0.0d0 3.2d0))) + nil) + +(my-assert + (typep 3.2 (quote (double-float 0.0d0 3.2d0))) + nil) + +(my-assert + (typep 3.2 (quote (float 0.0 3.2))) + t) + +(my-assert + (typep 3.2s0 (quote (float 0.0s0 3.2s0))) + t) + +(my-assert + (typep 2.0s0 (quote (short-float 0.0s0 3.0s0))) + t) + +(my-assert + (typep 2.0s0 (quote (single-float 0.0f0 3.0f0))) + #+(or allegro cmu sbcl) t + #-(or allegro cmu sbcl) nil) + +(my-assert + (typep 2.0 (quote (single-float 0.0f0 3.0f0))) + t) + +(my-assert + (typep 2.0d0 (quote (double-float 0.0d0 3.0d0))) + t) + +(my-assert + (typep 3.0d0 (quote (double-float 0.0d0 3.0d0))) + t) + +(my-assert + (typep 3.0d0 (quote (double-float 0.0d0 (3.0d0)))) + nil) + +(my-assert + (typep 4 (quote (mod 4))) + nil) + +(my-assert + (typep 4 (quote (mod 5))) + t) + +(my-assert + (typep 4 (quote (rational 2 5))) + t) + +(my-assert + (typep 4 (quote (rational 2 7/2))) + nil) + +(my-assert + (typep 4 (quote (rational 2 9/2))) + t) + +(my-assert + (typep 4 (quote (rational 2 4))) + t) + +(my-assert + (typep 4/3 (quote (rational 2 4))) + nil) + +(my-assert + (typep 2 (quote (rational 2 4))) + t) + +(my-assert + (typep "abcd" (quote string)) + t) + +(my-assert + (typep "abcd" (quote (string 4))) + t) + +(my-assert + (typep "abcd" (quote (string 43))) + nil) + +(my-assert + (typep '#(2 3) (quote (complex integer))) + nil) + +(my-assert + (typep '#(2 3) (quote complex)) + nil) + +(my-assert + (typep #c(2 3) (quote complex)) + t) + +(my-assert + (typep #c(2 3) (quote (complex integer))) + t) + +(my-assert + (typep #c(2 3) (quote (complex float))) + nil) + +(my-assert + (typep #c(2 3) (quote (complex symbol))) + #+(or cmu sbcl) error + #-(or cmu sbcl) nil) + +(my-assert + (typep '#(a b c d) (quote vector)) + t) + +(my-assert + (typep '#(a b c d) (quote (vector * 4))) + t) + +#| +;; +;; hängt von (upgraded-array-element-type 'symbol) ab! +(typep '#(a b c d) (quote (vector symbol 4))) +nil +|# + +(my-assert + (typep (quote a) (quote (symbol cons))) + error) + +(my-assert + (typep (quote a) (quote (or cons symbol))) + t) + +(my-assert + (typep (quote a) (quote (or cons number))) + nil) + +(my-assert + (typep (quote a) (quote (or atom number))) + t) + +(my-assert + (typep (quote a) (quote (and atom number))) + nil) + +(my-assert + (typep (quote 2) (quote (and atom number))) + t) + +(my-assert + (typep (quote 2) (quote (member 1 2 3))) + t) + +(my-assert + (typep (quote 2) (quote (member 1 3))) + nil) + +(my-assert + (typep (quote 2) (quote (not (member 1 3)))) + t) + +(my-assert + (typep (quote 2) (quote (not (member 1 2 3)))) + nil) + +(my-assert + (typep 2 (quote (and number (not symbol)))) + t) + +(my-assert + (typep 2 (quote (and string (not symbol)))) + nil) + +(my-assert + (typep 2 (quote (or string (not symbol)))) + t) + +(my-assert + (typep (quote cons) (quote function)) + nil) + +(my-assert + (typep (quote cons) (quote (satisfies functionp))) + nil) + +(my-assert + (typep (quote cons) (quote (satisfies not))) + nil) + +(my-assert + (typep (quote nil) (quote (satisfies not))) + t) + +(my-assert + (typep (quote nil) nil) + nil) + +(my-assert + (typep (quote t) nil) + nil) + +(my-assert + (subtypep (quote cons) t) + t) + +(my-assert + (subtypep nil (quote cons)) + t) + +(my-assert + (subtypep (quote cons) (quote list)) + t) + +(my-assert + (subtypep (quote cons) (quote (or atom cons))) + t) + +(my-assert + (subtypep (quote cons) (quote (and atom cons))) + nil) + +(my-assert + (subtypep (quote cons) (quote (not atom))) + #-(or clisp akcl allegro) t + #+(or clisp akcl allegro) nil + "Type atom: is equivalent to (not cons)") + +(my-assert + (subtypep (quote list) (quote (not atom))) + nil) + +(my-assert + (subtypep (quote (integer 1 5)) (quote (integer 0 7))) + t) + +(my-assert + (subtypep (quote (integer 1 5)) (quote (integer 0 (5)))) + nil) + +(my-assert + (subtypep (quote (integer 1 5)) (quote (integer 0 5))) + t) + +(my-assert + (subtypep (quote (integer 1 5)) (quote (mod 5))) + nil) + +(my-assert + (subtypep (quote (integer 1 (5))) (quote (mod 5))) + t) + +(my-assert + (subtypep '(or (integer 1 (5) float)) + '(or float (mod 5))) + #+(or xcl clisp ecls) t + #+(or allegro cmu sbcl) error + #-(or xcl clisp allegro cmu sbcl ecls) unknown) + +(my-assert + (subtypep '(or (integer 1 (5)) float) + '(or float (mod 5))) + t) + +(my-assert + (subtypep '(and number (float 1.0 (5.0))) + '(or float (mod 5))) + t) + +(my-assert + (subtypep '(and number (not (float 1.0 (5.0)))) + '(or float (mod 5))) + nil) + + +(my-assert + (subtypep '(and float (not (float 1.0 (5.0)))) + '(or float (mod 5))) + t + "a float that is not in [1-5[ is a subtype of float") + +(my-assert + (subtypep '(and float (not (float 1.0 (5.0)))) + '(or (float * 1.0) (float * 5.0))) + nil) + +(my-assert + (subtypep '(satisfies consp) + 'list) + nil) + +(my-assert + (subtypep (quote simple-string) (quote array)) + t) + +(my-assert + (deftype mod1 (n) `(and number (float 0.0 (,n)))) + mod1) + +(my-assert + (typep 4.1 (quote (mod1 5.0))) + t) + +(my-assert + (typep 4.1 (quote (mod1 4.1))) + nil) + +(my-assert + (subtypep (quote (float 2.3 6.7)) (quote (mod1 6.8))) + t) + +(my-assert + (subtypep (quote (float 2.3 6.7)) (quote (mod1 6.7))) + nil) + +(my-assert + (defun beliebiger-test (a) (member a (quote (u i v x)))) + beliebiger-test) + +(my-assert + (not (null (typep (quote u) (quote (satisfies beliebiger-test))))) + t) + +(my-assert + (typep (quote a) (quote (satisfies beliebiger-test))) + nil) + +;; This looks like asking a bit _too_ much +;; of the type system [pve] +(my-assert + (subtypep (quote (member u i)) (quote (satisfies beliebiger-test))) + #-(or cmu sbcl) t + #+(or cmu sbcl) nil) + +(my-assert + (subtypep (quote (or (member u i))) (quote (satisfies beliebiger-test))) + #-(or cmu sbcl) t + #+(or cmu sbcl) nil) + + +(my-assert + (subtypep (quote (or (member u i a))) (quote (satisfies beliebiger-test))) + nil) + +(my-assert + (subtypep (quote (satisfies beliebiger-test)) + (quote (member u i v x y))) + nil) + +(my-assert + (deftype beliebiger-typ nil (quote (satisfies beliebiger-test))) + beliebiger-typ) + +(my-assert + (not (null (typep (quote u) (quote beliebiger-typ)))) + t) + +(my-assert + (typep (quote a) (quote beliebiger-typ)) + nil) + +(my-assert + (subtypep (quote (member u i)) (quote beliebiger-typ)) + #-(or cmu sbcl) t + #+(or cmu sbcl) nil) + + +(my-assert + (subtypep (quote beliebiger-typ) (quote (member u i v x y))) + nil) + +(my-assert + (subtypep nil 'fixnum) t) + +(my-assert + (subtypep 'short-float 'float ) t) + +(my-assert + (subtypep 'single-float 'float ) t) + +(my-assert + (subtypep 'double-float 'float ) t) + +(my-assert + (subtypep 'long-float 'float ) t) + +(my-assert + (subtypep 'null 'symbol) t) + +(my-assert + (subtypep 'null 'list) t) + +(my-assert + (subtypep 'cons 'list) t) + +(my-assert + (subtypep 'string 'vector) t) + +(my-assert + (subtypep 'bit-vector 'vector) t) +(my-assert + (subtypep 'vector 'array) t) + +(my-assert + (subtypep 'simple-array 'array) t) + +(my-assert + (subtypep 'simple-vector 'simple-array) t) + +(my-assert + (subtypep 'simple-vector 'vector) t) + +(my-assert + (subtypep 'simple-string 'simple-array) t) + +(my-assert + (subtypep 'simple-bit-vector 'simple-array) t) + +(my-assert + (subtypep 'simple-string 'string) t) + +(my-assert + (subtypep 'simple-string 'vector) t) + +(my-assert + (subtypep 'simple-string 'simple-vector) nil) + +(my-assert + (subtypep 'simple-bit-vector 'bit-vector) t) + +(my-assert + (subtypep 'bit-vector 'vector) t) + +(my-assert + (subtypep 'simple-bit-vector 'simple-vector) nil) + +(my-assert + (subtypep 'unsigned-byte 'integer) t) + +(my-assert + (subtypep 'signed-byte 'integer) t) diff --git a/src/ansi-tests/unix-tests.lisp b/src/ansi-tests/unix-tests.lisp new file mode 100644 index 000000000..f39142c7e --- /dev/null +++ b/src/ansi-tests/unix-tests.lisp @@ -0,0 +1,52 @@ +(in-package :cl-user) + +(my-assert + (progn (ensure-directories-exist "test-dir/") t) + T) + +(my-assert + (#+cmu unix:unix-access + #+sbcl sb-unix:unix-access "test-dir" + #+cmu unix:r_ok + #+sbcl sb-unix:r_ok) + T) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir" #+cmu unix:w_ok #+sbcl sb-unix:w_ok) + T) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir" #+cmu unix:x_ok #+sbcl sb-unix:x_ok) + T) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir" #+cmu unix:f_ok #+sbcl sb-unix:f_ok) + T) + +(with-open-file (file "test-dir/a" + :direction :output + :if-exists :supersede) + (princ "hello world" file)) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir/a" #+cmu unix:r_ok #+sbcl sb-unix:r_ok) + T) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir/a" #+cmu unix:w_ok #+sbcl sb-unix:w_ok) + T) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir/a" #+cmu unix:x_ok #+sbcl sb-unix:x_ok) + NIL) + +(my-assert + (#+cmu unix:unix-access #+sbcl sb-unix:unix-access "test-dir/a" #+cmu unix:f_ok #+sbcl sb-unix:f_ok) + T) + +(my-assert + (progn + (#+cmu unix:unix-gettimeofday #+sbcl sb-unix:unix-gettimeofday) + t) + t) + diff --git a/src/bare.lsp.in b/src/bare.lsp.in new file mode 100644 index 000000000..119faf1a5 --- /dev/null +++ b/src/bare.lsp.in @@ -0,0 +1,56 @@ +;;; +;;; Configuration file for the bootstrapping version of ECLS +;;; +;;; * Set ourselves in the 'SYSTEM package +;;; +(setq *package* (find-package "SYSTEM")) + +;;; +;;; * Load Common-Lisp base library +;;; +(load "lsp/load.lsp") + +#ifdef CLOS +;;; +;;; * Load PCL-based Common-Lisp Object System +;;; +(setf sys::*gc-verbose* nil) +(load "clos/load.lsp") +#endif + +;;; +;;; * Load the compiler. +;;; +(load "cmp/load.lsp") + +;;; +;;; * By redefining *system-directory* ECLS will be able to +;;; find headers and libraries in the build directory. +;;; +(setq si::*system-directory* (namestring (sys::chdir "./"))) + +;;; +;;; * Add include path to not yet installed headers +;;; +(setq compiler::*cc-flags* (concatenate 'string compiler::*cc-flags* " -I@srcdir@/h -I@srcdir@/gmp ")) + +;;; +;;; * Beppe's defsystem utility +;;; +(load "@srcdir@/util/system.lsp") + +;;; +;;; * We redefine this to force generation of source files +;;; in the object directory -- source files help debugging +;;; with GDB. +;;; +(defun sbt::sbt-compile-file (&rest s) + (apply #'compiler::compile-file + (car s) + :c-file t :h-file t :data-file t :system-p t + (cdr s))) + +;;; +;;; * Go back to build directory to start compiling +;;; +(setq *features* (remove :ecls-min *features*)) diff --git a/src/c/Makefile.in b/src/c/Makefile.in new file mode 100644 index 000000000..d6f0faa8b --- /dev/null +++ b/src/c/Makefile.in @@ -0,0 +1,131 @@ +# +# Makefile for ECLS core library +# +top_srcdir= @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +MACHINE = @MACHINE@ + +# Programs used by "make": +# +CC = @CC@ +DEFS = -D$(MACHINE) +CFLAGS = -c -I../h -I$(HDIR) -I$(top_srcdir)/gc @CFLAGS@ $(DEFS) +#ifndef HAVE_LOCAL_GMP +CFLAGS += -I$(top_srcdir)/gmp +#endif + +SHELL = /bin/sh +RM = @RM@ + +#ifdef MSDOS +DPP = dpp.exe +#else +DPP = ./dpp +#endif + +# Data for installation +# +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +libdir = @libdir@ + +# Files + +HDIR = $(top_srcdir)/h +HFILES = ../h/config.h $(HDIR)/ecls.h $(HDIR)/ecls-cmp.h\ + $(HDIR)/machines.h $(HDIR)/object.h $(HDIR)/cs.h $(HDIR)/stacks.h\ + $(HDIR)/external.h $(HDIR)/lisp_external.h $(HDIR)/eval.h\ + $(HDIR)/number.h $(HDIR)/page.h $(HDIR)/unify.h\ + $(HDIR)/lwp.h $(HDIR)/critical.h +#ifdef GBC_BOEHM +ALLOC = alloc_2.o +#else +ALLOC = alloc.o gbc.o +#endif +OBJS = main.o $(ALLOC) symbol.o package.o list.o\ + apply.o eval.o interpreter.o compiler.o disassembler.o \ + lex.o reference.o character.o\ + file.o read.o print.o error.o string.o cfun.o\ + typespec.o assignment.o \ + predicate.o big.o number.o\ + num_pred.o num_comp.o num_arith.o num_sfun.o num_co.o\ + num_log.o num_rand.o array.o sequence.o cmpaux.o\ + macros.o backq.o stacks.o \ + time.o unixint.o\ + mapfun.o multival.o hash.o format.o pathname.o\ + structure.o load.o unixfsys.o unixsys.o \ + all_keywords.o all_symbols.o all_functions.o init.o +#ifdef THREADS +OBJS += lwp.o +#endif +#ifdef LOCATIVE +OBJS += unify.o +#endif +#if defined(TCP) || defined(CLX) +OBJS += tcp.o +#endif +#ifdef CLOS +OBJS += clos.o instance.o gfun.o +#endif +#ifdef TK +OBJS += tclBasic.o tkMain.o +#endif +#ifdef PROFILE +OBJS += profile.o +#endif +#ifdef MSDOS +OBJS += dostimes.o dosdummy.o +#endif + +.SUFFIXES: .c .o .d + +.c.o: $(HFILES) + $(CC) $(CFLAGS) -o $@ $< +.d.c: $(DPP) $(HFILES) + $(DPP) $< $@ + +all: $(DPP) ../libecls.a cinit.o +.PHONY: all + +install: $(HFILES) + for i in $(HFILES); do $(INSTALL_DATA) $$i $(PREFIX)$(libdir)/h; done + +../libecls.a: $(OBJS) + ar cr $@ $(OBJS) + ranlib $@ + +clean: + $(RM) *.c $(OBJS) ../libecls.a cinit.o core a.out + +# Build rules + +./dpp : $(srcdir)/dpp.c + $(CC) @CFLAGS@ -I$(HDIR) $(srcdir)/dpp.c -o $@ + +dpp.exe : $(srcdir)/dpp.c + make dpp + coff2exe dpp + $(RM) dpp + +# +# Some files may break due to gcc optimizations +# +#apply.o: apply.c $(HFILES) $(HDIR)/cs.h +# dangerous to optimize due to assembler hack +# $(CC) $(CFLAGS) -O0 -g apply.c -o $@ +#ifdef sgi +# gcc optimization causes trouble +assignment.o: assignment.c $(HFILES) + $(CC) $(CFLAGS) -g assignment.c -o $@ +#else +# $(CC) $(CFLAGS) assignment.c -o $@ +#endif +#ifdef sgi +# gcc optimization causes trouble +gbc.o: gbc.c $(HFILES) + $(CC) $(CFLAGS) -g gbc.c -o $@ +#else +# $(CC) $(CFLAGS) gbc.c -o $@ +#endif diff --git a/src/c/all_functions.d b/src/c/all_functions.d new file mode 100644 index 000000000..7ff0706f6 --- /dev/null +++ b/src/c/all_functions.d @@ -0,0 +1,889 @@ +#define _ARGS(x) (int n, ...) + +#include "ecls.h" +#include "page.h" + +struct function_info { + const char *name; + cl_object (*f)(int, ...); + short type; +}; + +#define form 2 +#define cl 0 +#define si 1 + +static const struct function_info all_functions[] = { + + /* alloc.c */ + +#if !defined(GBC_BOEHM) + {"ALLOCATE", siLallocate, si}, + {"ALLOCATED-PAGES", siLallocated_pages, si}, + {"MAXIMUM-ALLOCATABLE-PAGES", siLmaxpage, si}, + {"ALLOCATE-CONTIGUOUS-PAGES", siLalloc_contpage, si}, + {"ALLOCATED-CONTIGUOUS-PAGES", siLncbpage, si}, + {"MAXIMUM-CONTIGUOUS-PAGES", siLmaxcbpage, si}, + {"GET-HOLE-SIZE", siLget_hole_size, si}, + {"SET-HOLE-SIZE", siLset_hole_size, si}, + {"IGNORE-MAXIMUM-PAGES", siLignore_maximum_pages, si}, +#endif /* !GBC_BOEHM */ + + /* alloc_2.c */ + +#ifdef GBC_BOEHM + {"GC", Lgc, cl}, +#endif + + /* array.c */ + + {"MAKE-PURE-ARRAY", siLmake_pure_array, si}, + {"MAKE-VECTOR", siLmake_vector, si}, + {"AREF", Laref, cl}, + {"ASET", siLaset, si}, + {"ARRAY-ELEMENT-TYPE", Larray_element_type, cl}, + {"ARRAY-RANK", Larray_rank, cl}, + {"ARRAY-DIMENSION", Larray_dimension, cl}, + {"ARRAY-TOTAL-SIZE", Larray_total_size, cl}, + {"ADJUSTABLE-ARRAY-P", Ladjustable_array_p, cl}, + {"DISPLACED-ARRAY-P", siLdisplaced_array_p, si}, + + {"SVREF", Lsvref, cl}, + {"SVSET", siLsvset, si}, + + {"ARRAY-HAS-FILL-POINTER-P", Larray_has_fill_pointer_p, cl}, + {"FILL-POINTER", Lfill_pointer, cl}, + {"FILL-POINTER-SET", siLfill_pointer_set, si}, + + {"REPLACE-ARRAY", siLreplace_array, si}, + + /* assignment.c */ + + {"CLEAR-COMPILER-PROPERTIES", siLclear_compiler_properties, si}, + {"SETQ", NULL, form}, + {"PSETQ", NULL, form}, + {"SET", Lset, cl}, + {"FSET", siLfset, si}, + {"MULTIPLE-VALUE-SETQ", NULL, form}, + {"MAKUNBOUND", Lmakunbound, cl}, + {"FMAKUNBOUND", Lfmakunbound, cl}, +#if 0 + {"SETF", NULL, form}, + {"PUSH", NULL, form}, + {"POP", NULL, form}, + {"INCF", NULL, form}, + {"DECF", NULL, form}, +#endif + {"SETF-NAMEP", siLsetf_namep, si}, + + /* block.c */ + + {"BLOCK", NULL, form}, + {"RETURN-FROM", NULL, form}, + {"RETURN", NULL, form}, + + /* catch.c */ + + {"CATCH", NULL, form}, + {"UNWIND-PROTECT", NULL, form}, + {"THROW", NULL, form}, + + /* cfun.c */ + + {"COMPILED-FUNCTION-NAME", siLcompiled_function_name, si}, + {"COMPILED-FUNCTION-BLOCK", siLcompiled_function_block, si}, + + /* character.d */ + + {"STANDARD-CHAR-P", Lstandard_char_p, cl}, + {"GRAPHIC-CHAR-P", Lgraphic_char_p, cl}, + {"ALPHA-CHAR-P", Lalpha_char_p, cl}, + {"UPPER-CASE-P", Lupper_case_p, cl}, + {"LOWER-CASE-P", Llower_case_p, cl}, + {"BOTH-CASE-P", Lboth_case_p, cl}, + {"DIGIT-CHAR-P", Ldigit_char_p, cl}, + {"ALPHANUMERICP", Lalphanumericp, cl}, + {"CHAR=", Lchar_eq, cl}, + {"CHAR/=", Lchar_neq, cl}, + {"CHAR<", Lchar_l, cl}, + {"CHAR>", Lchar_g, cl}, + {"CHAR<=", Lchar_le, cl}, + {"CHAR>=", Lchar_ge, cl}, + {"CHAR-EQUAL", Lchar_equal, cl}, + {"CHAR-NOT-EQUAL", Lchar_not_equal, cl}, + {"CHAR-LESSP", Lchar_lessp, cl}, + {"CHAR-GREATERP", Lchar_greaterp, cl}, + {"CHAR-NOT-GREATERP", Lchar_not_greaterp, cl}, + {"CHAR-NOT-LESSP", Lchar_not_lessp, cl}, + {"CHARACTER", Lcharacter, cl}, + {"CHAR-CODE", Lchar_code, cl}, + {"CODE-CHAR", Lcode_char, cl}, + {"CHAR-UPCASE", Lchar_upcase, cl}, + {"CHAR-DOWNCASE", Lchar_downcase, cl}, + {"DIGIT-CHAR", Ldigit_char, cl}, + {"CHAR-INT", Lchar_int, cl}, + {"INT-CHAR", Lint_char, cl}, + {"CHAR-NAME", Lchar_name, cl}, + {"NAME-CHAR", Lname_char, cl}, + + /* cmpaux.c */ + + {"SPECIALP", siLspecialp, si}, + + /* conditional.c */ + + {"IF", NULL, form}, + {"COND", NULL, form}, + {"CASE", NULL, form}, + {"WHEN", NULL, form}, + {"UNLESS", NULL, form}, + + /* disassembler.c */ + {"BC-DISASSEMBLE", siLbc_disassemble, si}, + {"BC-SPLIT", siLbc_split, si}, + + /* error.c */ + +#if defined(FRAME_CHAIN) && !defined(RUNTIME) + {"BT", siLbacktrace, si}, +#endif + {"ERROR", Lerror, cl}, + {"CERROR", Lcerror, cl}, + {"UNIVERSAL-ERROR-HANDLER", siLuniversal_error_handler, si}, + + /* eval.c */ + + {"EVAL", Leval, cl}, + {"EVALHOOK", Levalhook, cl}, + {"APPLYHOOK", Lapplyhook, cl}, + {"CONSTANTP", Lconstantp, cl}, + {"UNLINK-SYMBOL", siLunlink_symbol, si}, + {"APPLY", Lapply, cl}, + {"FUNCALL", Lfuncall, cl}, + + /* file.d */ + + {"MAKE-SYNONYM-STREAM", Lmake_synonym_stream, cl}, + {"MAKE-BROADCAST-STREAM", Lmake_broadcast_stream, cl}, + {"MAKE-CONCATENATED-STREAM", Lmake_concatenated_stream, cl}, + {"MAKE-TWO-WAY-STREAM", Lmake_two_way_stream, cl}, + {"MAKE-ECHO-STREAM", Lmake_echo_stream, cl}, + {"MAKE-STRING-INPUT-STREAM", Lmake_string_input_stream, cl}, + {"MAKE-STRING-OUTPUT-STREAM", Lmake_string_output_stream, cl}, + {"GET-OUTPUT-STREAM-STRING", Lget_output_stream_string, cl}, + + {"OUTPUT-STREAM-STRING", siLoutput_stream_string, si}, + + {"STREAMP", Lstreamp, cl}, + {"INPUT-STREAM-P", Linput_stream_p, cl}, + {"OUTPUT-STREAM-P", Loutput_stream_p, cl}, + {"STREAM-ELEMENT-TYPE", Lstream_element_type, cl}, + {"CLOSE", Lclose, cl}, + {"OPEN", Lopen, cl}, + {"FILE-POSITION", Lfile_position, cl}, + {"FILE-LENGTH", Lfile_length, cl}, + {"OPEN-STREAM-P", Lopen_stream_p, cl}, + {"GET-STRING-INPUT-STREAM-INDEX", siLget_string_input_stream_index, si}, + {"MAKE-STRING-OUTPUT-STREAM-FROM-STRING", siLmake_string_output_stream_from_string, si}, + {"COPY-STREAM", siLcopy_stream, si}, + + /* format. c */ + + {"FORMAT", Lformat, cl}, + + /* gbc.c */ + +#if !defined(GBC_BOEHM) + {"ROOM-REPORT", siLroom_report, si}, + {"RESET-GC-COUNT", siLreset_gc_count, si}, + {"GC", Lgc, cl}, + {"GC-TIME", siLgc_time, si}, +#endif + + /* gfun.c */ +#ifdef CLOS + {"ALLOCATE-GFUN", siLallocate_gfun, si}, + {"GFUN-NAME", siLgfun_name, si}, + {"GFUN-NAME-SET", siLgfun_name_set, si}, + {"GFUN-METHOD-HT", siLgfun_method_ht, si}, + {"GFUN-METHOD-HT-SET", siLgfun_method_ht_set, si}, + {"GFUN-SPEC-HOW-REF", siLgfun_spec_how_ref, si}, + {"GFUN-SPEC-HOW-SET", siLgfun_spec_how_set, si}, + {"GFUN-INSTANCE", siLgfun_instance, si}, + {"GFUN-INSTANCE-SET", siLgfun_instance_set, si}, + {"GFUNP", siLgfunp, si}, + {"METHOD-HT-GET", siLmethod_ht_get, si}, + {"SET-COMPILED-FUNCTION-NAME", siLset_compiled_function_name, si}, +#endif CLOS + + /* hash.d */ + + {"MAKE-HASH-TABLE", Lmake_hash_table, cl}, + {"HASH-TABLE-P", Lhash_table_p, cl}, + {"GETHASH", Lgethash, cl}, + {"REMHASH", Lremhash, cl}, + {"MAPHASH", Lmaphash, cl}, + {"CLRHASH", Lclrhash, cl}, + {"HASH-TABLE-COUNT", Lhash_table_count, cl}, + {"SXHASH", Lsxhash, cl}, + {"HASH-SET", siLhash_set, si}, + {"HASH-TABLE-REHASH-SIZE", Lhash_table_rehash_size, cl}, + {"HASH-TABLE-REHASH-THRESHOLD", Lhash_table_rehash_threshold, cl}, + + /* instance.c */ +#ifdef CLOS + {"ALLOCATE-INSTANCE", siLallocate_instance, si}, + {"CHANGE-INSTANCE", siLchange_instance, si}, + {"INSTANCE-REF-SAFE", siLinstance_ref_safe, si}, + {"INSTANCE-REF", siLinstance_ref, si}, + {"INSTANCE-SET", siLinstance_set, si}, + {"INSTANCE-CLASS", siLinstance_class, si}, + {"INSTANCE-CLASS-SET", siLinstance_class_set, si}, + {"INSTANCEP", siLinstancep, si}, + {"SL-BOUNDP", siLsl_boundp, si}, + {"SL-MAKUNBOUND", siLsl_makunbound, si}, +#endif CLOS + + /* interpreter.c */ + {"INTERPRETER-STACK", siLinterpreter_stack, si}, + {"MAKE-LAMBDA", siLmake_lambda, si}, + + /* iteration.c */ + + {"DO", NULL, form}, + {"DO*", NULL, form}, + {"DOLIST", NULL, form}, + {"DOTIMES", NULL, form}, + + /* lex.c */ + + {"LEX-ENV", siLlex_env, si}, + + /* let.c */ + + {"LET", NULL, form}, + {"LET*", NULL, form}, + {"MULTIPLE-VALUE-BIND", NULL, form}, + {"COMPILER-LET", NULL, form}, + {"FLET", NULL, form}, + {"LABELS", NULL, form}, + {"MACROLET", NULL, form}, + {"SYMBOL-MACROLET", NULL, form}, + + /* list.d */ + + {"CAR", Lcar, cl}, + {"CDR", Lcdr, cl}, + {"CAAR", Lcaar, cl}, + {"CADR", Lcadr, cl}, + {"CDAR", Lcdar, cl}, + {"CDDR", Lcddr, cl}, + {"CAAAR", Lcaaar, cl}, + {"CAADR", Lcaadr, cl}, + {"CADAR", Lcadar, cl}, + {"CADDR", Lcaddr, cl}, + {"CDAAR", Lcdaar, cl}, + {"CDADR", Lcdadr, cl}, + {"CDDAR", Lcddar, cl}, + {"CDDDR", Lcdddr, cl}, + {"CAAAAR", Lcaaaar, cl}, + {"CAAADR", Lcaaadr, cl}, + {"CAADAR", Lcaadar, cl}, + {"CAADDR", Lcaaddr, cl}, + {"CADAAR", Lcadaar, cl}, + {"CADADR", Lcadadr, cl}, + {"CADDAR", Lcaddar, cl}, + {"CADDDR", Lcadddr, cl}, + {"CDAAAR", Lcdaaar, cl}, + {"CDAADR", Lcdaadr, cl}, + {"CDADAR", Lcdadar, cl}, + {"CDADDR", Lcdaddr, cl}, + {"CDDAAR", Lcddaar, cl}, + {"CDDADR", Lcddadr, cl}, + {"CDDDAR", Lcdddar, cl}, + {"CDDDDR", Lcddddr, cl}, + + {"CONS", Lcons, cl}, + {"TREE-EQUAL", Ltree_equal, cl}, + {"ENDP", Lendp, cl}, + {"LIST-LENGTH", Llist_length, cl}, + {"NTH", Lnth, cl}, + + {"FIRST", Lcar, cl}, + {"SECOND", Lcadr, cl}, + {"THIRD", Lcaddr, cl}, + {"FOURTH", Lcadddr, cl}, + {"FIFTH", Lfifth, cl}, + {"SIXTH", Lsixth, cl}, + {"SEVENTH", Lseventh, cl}, + {"EIGHTH", Leighth, cl}, + {"NINTH", Lninth, cl}, + {"TENTH", Ltenth, cl}, + + {"REST", Lcdr, cl}, + {"NTHCDR", Lnthcdr, cl}, + {"LAST", Llast, cl}, + {"LIST", Llist, cl}, + {"LIST*", LlistA, cl}, + {"MAKE-LIST", Lmake_list, cl}, + {"APPEND", Lappend, cl}, + {"COPY-LIST", Lcopy_list, cl}, + {"COPY-ALIST", Lcopy_alist, cl}, + {"COPY-TREE", Lcopy_tree, cl}, + {"REVAPPEND", Lrevappend, cl}, + {"NCONC", Lnconc, cl}, + {"NRECONC", Lreconc, cl}, + + {"BUTLAST", Lbutlast, cl}, + {"NBUTLAST", Lnbutlast, cl}, + {"LDIFF", Lldiff, cl}, + {"RPLACA", Lrplaca, cl}, + {"RPLACD", Lrplacd, cl}, + {"SUBST", Lsubst, cl}, + {"SUBST-IF", Lsubst_if, cl}, + {"SUBST-IF-NOT", Lsubst_if_not, cl}, + {"NSUBST", Lnsubst, cl}, + {"NSUBST-IF", Lnsubst_if, cl}, + {"NSUBST-IF-NOT", Lnsubst_if_not, cl}, + {"SUBLIS", Lsublis, cl}, + {"NSUBLIS", Lnsublis, cl}, + {"MEMBER", Lmember, cl}, + {"MEMBER-IF", Lmember_if, cl}, + {"MEMBER-IF-NOT", Lmember_if_not, cl}, + {"MEMBER1", Lmember1, si}, + {"TAILP", Ltailp, cl}, + {"ADJOIN", Ladjoin, cl}, + + {"ACONS", Lacons, cl}, + {"PAIRLIS", Lpairlis, cl}, + {"ASSOC", Lassoc, cl}, + {"ASSOC-IF", Lassoc_if, cl}, + {"ASSOC-IF-NOT", Lassoc_if_not, cl}, + {"RASSOC", Lrassoc, cl}, + {"RASSOC-IF", Lrassoc_if, cl}, + {"RASSOC-IF-NOT", Lrassoc_if_not, cl}, + + {"MEMQ", siLmemq, si}, + + /* load.d */ + + {"LOAD", Lload, cl}, + {"LOAD-BINARY", siLload_binary, si}, + {"LOAD-SOURCE", siLload_source, si}, +#if 0 + {"FASLINK", siLfaslink, si}, +#endif + + /* lwp.d */ +#ifdef THREADS + {"THREAD-BREAK-IN", siLthread_break_in, si}, + {"THREAD-BREAK-QUIT", siLthread_break_quit, si}, + {"THREAD-BREAK-RESUME", siLthread_break_resume, si}, + {"MAKE-THREAD", Lmake_thread, cl}, + {"DEACTIVATE", Ldeactivate, cl}, + {"REACTIVATE", Lreactivate, cl}, + {"KILL-THREAD", Lkill_thread, cl}, + {"CURRENT-THREAD", Lcurrent_thread, cl}, + {"THREAD-STATUS", Lthread_status, cl}, + {"THREAD-LIST", Lthread_list, cl}, + {"MAKE-CONTINUATION", Lmake_continuation, cl}, + {"THREAD-OF", Lthread_of, cl}, + {"CONTINUATION-OF", Lcontinuation_of, cl}, + {"RESUME", Lresume, cl}, + + {"%DISABLE-SCHEDULER", Ldisable_scheduler, cl}, + {"%ENABLE-SCHEDULER", Lenable_scheduler, cl}, + {"%SUSPEND", Lsuspend, cl}, + {"%DELAY", Ldelay, cl}, + {"%THREAD-WAIT", Lthread_wait, cl}, + {"%THREAD-WAIT-WITH-TIMEOUT", Lthread_wait_with_timeout, cl}, +#endif THREADS + + /* macros.c */ + + {"MACROEXPAND", Lmacroexpand, cl}, + {"MACROEXPAND-1", Lmacroexpand_1, cl}, + + /* main.c */ + + {"QUIT", Lquit, cl}, + {"ARGC", siLargc, si}, + {"ARGV", siLargv, si}, + {"GETENV", siLgetenv, si}, + {"POINTER", siLaddress, si}, +#if !defined(MSDOS) && !defined(__NeXT) + {"MACHINE-INSTANCE", Lmachine_instance, cl}, + {"MACHINE-VERSION", Lmachine_version, cl}, + {"SOFTWARE-TYPE", Lsoftware_type, cl}, + {"SOFTWARE-VERSION", Lsoftware_version, cl}, +#endif MSDOS + + /* mapfun.c */ + + {"MAPCAR", Lmapcar, cl}, + {"MAPLIST", Lmaplist, cl}, + {"MAPC", Lmapc, cl}, + {"MAPL", Lmapl, cl}, + {"MAPCAN", Lmapcan, cl}, + {"MAPCON", Lmapcon, cl}, + + /* multival.c */ + + {"VALUES", Lvalues, cl}, + {"VALUES-LIST", Lvalues_list, cl}, + {"MULTIPLE-VALUE-CALL", NULL, form}, + {"MULTIPLE-VALUE-PROG1", NULL, form}, + {"MULTIPLE-VALUE-LIST", NULL, form}, + {"NTH-VALUE", NULL, form}, + + + /* num-arith.c */ + + {"+", Lplus, cl}, + {"-", Lminus, cl}, + {"*", Ltimes, cl}, + {"/", Ldivide, cl}, + {"1+", Lone_plus, cl}, + {"1-", Lone_minus, cl}, + {"CONJUGATE", Lconjugate, cl}, + {"GCD", Lgcd, cl}, + {"LCM", Llcm, cl}, + + + /* num_co.c */ + + {"FLOAT", Lfloat, cl}, + {"NUMERATOR", Lnumerator, cl}, + {"DENOMINATOR", Ldenominator, cl}, + {"FLOOR", Lfloor, cl}, + {"CEILING", Lceiling, cl}, + {"TRUNCATE", Ltruncate, cl}, + {"ROUND", Lround, cl}, + {"MOD", Lmod, cl}, + {"REM", Lrem, cl}, + {"DECODE-FLOAT", Ldecode_float, cl}, + {"SCALE-FLOAT", Lscale_float, cl}, + {"FLOAT-RADIX", Lfloat_radix, cl}, + {"FLOAT-SIGN", Lfloat_sign, cl}, + {"FLOAT-DIGITS", Lfloat_digits, cl}, + {"FLOAT-PRECISION", Lfloat_precision, cl}, + {"INTEGER-DECODE-FLOAT", Linteger_decode_float, cl}, + {"COMPLEX", Lcomplex, cl}, + {"REALPART", Lrealpart, cl}, + {"IMAGPART", Limagpart, cl}, + + /* num_comp.c */ + + {"=", Lall_the_same, cl}, + {"/=", Lall_different, cl}, + {"<", Lmonotonically_increasing, cl}, + {">", Lmonotonically_decreasing, cl}, + {"<=", Lmonotonically_nondecreasing, cl}, + {">=", Lmonotonically_nonincreasing, cl}, + {"MAX", Lmax, cl}, + {"MIN", Lmin, cl}, + + /* num_log.c */ + + {"LOGIOR", Llogior, cl}, + {"LOGXOR", Llogxor, cl}, + {"LOGAND", Llogand, cl}, + {"LOGEQV", Llogeqv, cl}, + {"BOOLE", Lboole, cl}, + {"LOGBITP", Llogbitp, cl}, + {"ASH", Lash, cl}, + {"LOGCOUNT", Llogcount, cl}, + {"INTEGER-LENGTH", Linteger_length, cl}, + {"BIT-ARRAY-OP", siLbit_array_op, si}, + + /* num_pred.c */ + + {"ZEROP", Lzerop, cl}, + {"PLUSP", Lplusp, cl}, + {"MINUSP", Lminusp, cl}, + {"ODDP", Loddp, cl}, + {"EVENP", Levenp, cl}, + {"NANI", siLnani, si}, + + /* num_rand.c */ + + {"RANDOM", Lrandom, cl}, + {"MAKE-RANDOM-STATE", Lmake_random_state, cl}, + {"RANDOM-STATE-P", Lrandom_state_p, cl}, + + /* num_sfun.c */ + + {"EXP", Lexp, cl}, + {"EXPT", Lexpt, cl}, + {"LOG", Llog, cl}, + {"SQRT", Lsqrt, cl}, + {"SIN", Lsin, cl}, + {"COS", Lcos, cl}, + {"TAN", Ltan, cl}, + {"ATAN", Latan, cl}, + {"SINH", Lsinh, cl}, + {"COSH", Lcosh, cl}, + {"TANH", Ltanh, cl}, + + /* package.d */ + + {"MAKE-PACKAGE", Lmake_package, cl}, + {"SELECT-PACKAGE", siLselect_package, si}, + {"FIND-PACKAGE", Lfind_package, cl}, + {"PACKAGE-NAME", Lpackage_name, cl}, + {"PACKAGE-NICKNAMES", Lpackage_nicknames, cl}, + {"RENAME-PACKAGE", Lrename_package, cl}, + {"PACKAGE-USE-LIST", Lpackage_use_list, cl}, + {"PACKAGE-USED-BY-LIST", Lpackage_used_by_list, cl}, + {"PACKAGE-SHADOWING-SYMBOLS", Lpackage_shadowing_symbols, cl}, + {"LIST-ALL-PACKAGES", Llist_all_packages, cl}, + {"INTERN", Lintern, cl}, + {"FIND-SYMBOL", Lfind_symbol, cl}, + {"UNINTERN", Lunintern, cl}, + {"EXPORT", Lexport, cl}, + {"UNEXPORT", Lunexport, cl}, + {"IMPORT", Limport, cl}, + {"SHADOWING-IMPORT", Lshadowing_import, cl}, + {"SHADOW", Lshadow, cl}, + {"USE-PACKAGE", Luse_package, cl}, + {"UNUSE-PACKAGE", Lunuse_package, cl}, + {"DELETE-PACKAGE", Ldelete_package, cl}, + + {"PACKAGE-SIZE", siLpackage_size, si}, + {"PACKAGE-INTERNAL", siLpackage_internal, si}, + {"PACKAGE-EXTERNAL", siLpackage_external, si}, + {"PACKAGE-LOCK", siLpackage_lock, si}, + + /* pathname.d */ + + {"PATHNAME", Lpathname, cl}, + {"PARSE-NAMESTRING", Lparse_namestring, cl}, + {"MERGE-PATHNAMES", Lmerge_pathnames, cl}, + {"MAKE-PATHNAME", Lmake_pathname, cl}, + {"PATHNAMEP", Lpathnamep, cl}, + {"PATHNAME-HOST", Lpathname_host, cl}, + {"PATHNAME-DEVICE", Lpathname_device, cl}, + {"PATHNAME-DIRECTORY", Lpathname_directory, cl}, + {"PATHNAME-NAME", Lpathname_name, cl}, + {"PATHNAME-TYPE", Lpathname_type, cl}, + {"PATHNAME-VERSION", Lpathname_version, cl}, + {"NAMESTRING", Lnamestring, cl}, + {"FILE-NAMESTRING", Lfile_namestring, cl}, + {"DIRECTORY-NAMESTRING", Ldirectory_namestring, cl}, + {"HOST-NAMESTRING", Lhost_namestring, cl}, + {"ENOUGH-NAMESTRING", Lenough_namestring, cl}, + {"LOGICAL-PATHNAME-P", siLlogical_pathname_p, si}, + {"PATHNAME-MATCH-P", Lpathname_match_p, cl}, + {"TRANSLATE-PATHNAME", Ltranslate_pathname, cl}, + {"TRANSLATE-LOGICAL-PATHNAME", Ltranslate_logical_pathname, cl}, + {"PATHNAME-TRANSLATIONS", siLpathname_translations, si}, + + /* predicate.c */ + + {"IDENTITY", Lidentity, cl}, + {"NULL", Lnull, cl}, + {"SYMBOLP", Lsymbolp, cl}, + {"ATOM", Latom, cl}, + {"CONSP", Lconsp, cl}, + {"LISTP", Llistp, cl}, + {"NUMBERP", Lnumberp, cl}, + {"INTEGERP", Lintegerp, cl}, + {"RATIONALP", Lrationalp, cl}, + {"FLOATP", Lfloatp, cl}, + {"REALP", Lrealp, cl}, + {"COMPLEXP", Lcomplexp, cl}, + {"CHARACTERP", Lcharacterp, cl}, + {"STRINGP", Lstringp, cl}, + {"BIT-VECTOR-P", Lbit_vector_p, cl}, + {"VECTORP", Lvectorp, cl}, + {"SIMPLE-STRING-P", Lsimple_string_p, cl}, + {"SIMPLE-BIT-VECTOR-P", Lsimple_bit_vector_p, cl}, + {"SIMPLE-VECTOR-P", Lsimple_vector_p, cl}, + {"ARRAYP", Larrayp, cl}, + {"PACKAGEP", Lpackagep, cl}, + {"FUNCTIONP", Lfunctionp, cl}, + {"COMPILED-FUNCTION-P", Lcompiled_function_p, cl}, + {"COMMONP", Lcommonp, cl}, + + {"EQ", Leq, cl}, + {"EQL", Leql, cl}, + {"EQUAL", Lequal, cl}, + {"EQUALP", Lequalp, cl}, + + {"NOT", Lnull, cl}, + + {"CONTAINS-SHARP-COMMA", siLcontains_sharp_comma, si}, + + {"FIXNUMP", siLfixnump, si}, + + /* print.d */ + + {"WRITE", Lwrite, cl}, + {"PRIN1", Lprin1, cl}, + {"PRINT", Lprint, cl}, + {"PPRINT", Lpprint, cl}, + {"PRINC", Lprinc, cl}, + {"WRITE-CHAR", Lwrite_char, cl}, + {"WRITE-STRING", Lwrite_string, cl}, + {"WRITE-LINE", Lwrite_line, cl}, + {"WRITE-BYTE", Lwrite_byte, cl}, + {"WRITE-BYTES", Lwrite_bytes, si}, + {"TERPRI", Lterpri, cl}, + {"FRESH-LINE", Lfresh_line, cl}, + {"FINISH-OUTPUT", Lforce_output, cl}, + {"FORCE-OUTPUT", Lforce_output, cl}, + {"CLEAR-OUTPUT", Lclear_output, cl}, + + /* profile.c */ +#ifdef PROFILE + {"PROFILE", siLprofile, si}, + {"CLEAR-PROFILE", siLclear_profile, si}, + {"DISPLAY-PROFILE", siLdisplay_profile, si}, +#endif PROFILE + + /* prog.c */ + + {"TAGBODY", NULL, form}, + {"PROG", NULL, form}, + {"PROG*", NULL, form}, + {"GO", NULL, form}, + {"PROGV", NULL, form}, + {"PROGN", NULL, form}, + {"PROG1", NULL, form}, + {"PROG2", NULL, form}, + + /* read.d */ + + {"READ", Lread, cl}, + {"READ-PRESERVING-WHITESPACE", Lread_preserving_whitespace, cl}, + {"READ-DELIMITED-LIST", Lread_delimited_list, cl}, + {"READ-LINE", Lread_line, cl}, + {"READ-CHAR", Lread_char, cl}, + {"UNREAD-CHAR", Lunread_char, cl}, + {"PEEK-CHAR", Lpeek_char, cl}, + {"LISTEN", Llisten, cl}, + {"READ-CHAR-NO-HANG", Lread_char_no_hang, cl}, + {"CLEAR-INPUT", Lclear_input, cl}, + + {"PARSE-INTEGER", Lparse_integer, cl}, + + {"READ-BYTE", Lread_byte, cl}, + {"READ-BYTES", Lread_bytes, si}, + + {"COPY-READTABLE", Lcopy_readtable, cl}, + {"READTABLEP", Lreadtablep, cl}, + {"SET-SYNTAX-FROM-CHAR", Lset_syntax_from_char, cl}, + {"SET-MACRO-CHARACTER", Lset_macro_character, cl}, + {"GET-MACRO-CHARACTER", Lget_macro_character, cl}, + {"MAKE-DISPATCH-MACRO-CHARACTER", Lmake_dispatch_macro_character, cl}, + {"SET-DISPATCH-MACRO-CHARACTER", Lset_dispatch_macro_character, cl}, + {"GET-DISPATCH-MACRO-CHARACTER", Lget_dispatch_macro_character, cl}, + {"SHARP-COMMA-READER-FOR-COMPILER", siLsharp_comma_reader_for_compiler, si}, + {"STRING-TO-OBJECT", siLstring_to_object, si}, + {"STANDARD-READTABLE", siLstandard_readtable, si}, + + /* reference.c */ + + {"SYMBOL-FUNCTION", Lsymbol_function, cl}, + {"FBOUNDP", Lfboundp, cl}, + {"QUOTE", NULL, form}, + {"SYMBOL-VALUE", Lsymbol_value, cl}, + {"BOUNDP", Lboundp, cl}, + {"MACRO-FUNCTION", Lmacro_function, cl}, + {"SPECIAL-FORM-P", Lspecial_form_p, cl}, + {"COERCE-TO-FUNCTION", siLcoerce_to_function, si}, + {"FUNCTION", NULL, form}, + {"PROCESS-DECLARATIONS", siLprocess_declarations, si}, + {"PROCESS-LAMBDA-LIST", siLprocess_lambda_list, si}, + + /* sequence.d */ + + {"ELT", Lelt, cl}, + {"ELT-SET", siLelt_set, si}, + {"SUBSEQ", Lsubseq, cl}, + {"COPY-SEQ", Lcopy_seq, cl}, + {"LENGTH", Llength, cl}, + {"REVERSE", Lreverse, cl}, + {"NREVERSE", Lnreverse, cl}, + + /* stacks.c */ + + {"IHS-TOP", siLihs_top, si}, + {"IHS-FUN", siLihs_fun, si}, + {"IHS-ENV", siLihs_env, si}, + {"FRS-TOP", siLfrs_top, si}, + {"FRS-BDS", siLfrs_bds, si}, + {"FRS-CLASS", siLfrs_class, si}, + {"FRS-TAG", siLfrs_tag, si}, + {"FRS-IHS", siLfrs_ihs, si}, + {"BDS-TOP", siLbds_top, si}, + {"BDS-VAR", siLbds_var, si}, + {"BDS-VAL", siLbds_val, si}, + {"SCH-FRS-BASE", siLsch_frs_base, si}, + {"RESET-STACK-LIMITS", siLreset_stack_limits, si}, + + /* string.d */ + + {"CHAR", Lchar, cl}, + {"CHAR-SET", siLchar_set, si}, + {"SCHAR", Lchar, cl}, + {"SCHAR-SET", siLchar_set, si}, + {"STRING=", Lstring_eq, cl}, + {"STRING-EQUAL", Lstring_equal, cl}, + {"STRING<", Lstring_l, cl}, + {"STRING>", Lstring_g, cl}, + {"STRING<=", Lstring_le, cl}, + {"STRING>=", Lstring_ge, cl}, + {"STRING/=", Lstring_neq, cl}, + {"STRING-LESSP", Lstring_lessp, cl}, + {"STRING-GREATERP", Lstring_greaterp, cl}, + {"STRING-NOT-LESSP", Lstring_not_lessp, cl}, + {"STRING-NOT-GREATERP", Lstring_not_greaterp, cl}, + {"STRING-NOT-EQUAL", Lstring_not_equal, cl}, + {"MAKE-STRING", Lmake_string, cl}, + {"STRING-TRIM", Lstring_trim, cl}, + {"STRING-LEFT-TRIM", Lstring_left_trim, cl}, + {"STRING-RIGHT-TRIM", Lstring_right_trim, cl}, + {"STRING-UPCASE", Lstring_upcase, cl}, + {"STRING-DOWNCASE", Lstring_downcase, cl}, + {"STRING-CAPITALIZE", Lstring_capitalize, cl}, + {"NSTRING-UPCASE", Lnstring_upcase, cl}, + {"NSTRING-DOWNCASE", Lnstring_downcase, cl}, + {"NSTRING-CAPITALIZE", Lnstring_capitalize, cl}, + {"STRING", Lstring, cl}, + {"STRING-CONCATENATE", siLstring_concatenate, si}, + + /* structure.c */ + + {"MAKE-STRUCTURE", siLmake_structure, si}, + {"COPY-STRUCTURE", siLcopy_structure, si}, + {"STRUCTURE-NAME", siLstructure_name, si}, + {"STRUCTURE-REF", siLstructure_ref, si}, + {"STRUCTURE-SET", siLstructure_set, si}, + {"STRUCTUREP", siLstructurep, si}, + {"STRUCTURE-SUBTYPE-P", siLstructure_subtype_p, si}, + {"RPLACA-NTHCDR", siLrplaca_nthcdr, si}, + {"LIST-NTH", siLlist_nth, si}, + + /* symbol.d */ + + {"GET", Lget, cl}, + {"REMPROP", Lremprop, cl}, + {"SYMBOL-PLIST", Lsymbol_plist, cl}, + {"GETF", Lgetf, cl}, + {"GET-PROPERTIES", Lget_properties, cl}, + {"SYMBOL-NAME", Lsymbol_name, cl}, + {"MAKE-SYMBOL", Lmake_symbol, cl}, + {"COPY-SYMBOL", Lcopy_symbol, cl}, + {"GENSYM", Lgensym, cl}, + {"GENTEMP", Lgentemp, cl}, + {"SYMBOL-PACKAGE", Lsymbol_package, cl}, + {"KEYWORDP", Lkeywordp, cl}, + {"PUT-F", siLput_f, si}, + {"REM-F", siLrem_f, si}, + {"SET-SYMBOL-PLIST", siLset_symbol_plist, si}, + {"PUTPROP", siLputprop, si}, + {"PUT-PROPERTIES", siLput_properties, si}, + + /* tcp.c */ +#ifdef TCP + {"OPEN-CLIENT-STREAM", Lopen_client_stream, si}, + {"OPEN-SERVER-STREAM", Lopen_server_stream, si}, +#endif + + /* time.c */ + + {"GET-UNIVERSAL-TIME", Lget_universal_time, cl}, + {"SLEEP", Lsleep, cl}, + {"GET-INTERNAL-RUN-TIME", Lget_internal_run_time, cl}, + {"GET-INTERNAL-REAL-TIME", Lget_internal_real_time, cl}, + {"GET-LOCAL-TIME-ZONE", Lget_local_time_zone, si}, + {"DAYLIGHT-SAVING-TIME-P", Ldaylight_saving_timep, si}, + + /* toplevel.c */ + + {"LAMBDA", NULL, form}, + {"NAMED-LAMBDA", NULL, form}, + {"*MAKE-SPECIAL", siLAmake_special, si}, + {"*MAKE-CONSTANT", siLAmake_constant, si}, + {"EVAL-WHEN", NULL, form}, + {"THE", NULL, form}, + {"DECLARE", NULL, form}, + {"LOCALLY", NULL, form}, + + /* typespec.c */ + + {"TYPE-OF", Ltype_of, cl}, + + /* unify.d */ +#ifdef LOCATIVE + {"TRAIL-MARK", Ltrail_mark, si}, + {"TRAIL-UNMARK", Ltrail_unmark, si}, + {"TRAIL-RESTORE", Ltrail_restore, si}, + {"GET-VARIABLE", NULL, form}, + {"GET-VALUE", Lget_value, si}, + {"GET-CONSTANT", Lget_constant, si}, + {"GET-NIL", Lget_nil, si}, + {"GET-CONS", Lget_cons, si}, + {"GET-INSTANCE", Lget_instance, si}, /* Mauro */ + {"UNIFY-SLOT", Lunify_slot, si}, + {"UNIFY-VALUE", Lunify_value, si}, + {"UNIFY-CONSTANT", Lunify_constant, si}, + {"UNIFY-NIL", Lunify_nil, si}, + {"MAKE-LOCATIVE", Lmake_locative, si}, + {"LOCATIVEP", Llocativep, si}, + {"UNBOUNDP", Lunboundp, si}, + {"MAKE-VARIABLE", Lmake_variable, si}, + {"DEREFERENCE", Ldereference, si}, +#endif LOCATIVE + + /* unixint.c */ + +#ifdef unix + {"CATCH-BAD-SIGNALS", siLcatch_bad_signals, si}, + {"UNCATCH-BAD-SIGNALS", siLuncatch_bad_signals, si}, +#endif unix + + /* unixfsys.c */ + + {"TRUENAME", Ltruename, cl}, + {"RENAME-FILE", Lrename_file, cl}, + {"DELETE-FILE", Ldelete_file, cl}, + {"PROBE-FILE", Lprobe_file, cl}, + {"FILE-WRITE-DATE", Lfile_write_date, cl}, + {"FILE-AUTHOR", Lfile_author, cl}, + {"USER-HOMEDIR-PATHNAME", Luser_homedir_pathname, cl}, + {"STRING-MATCH", siLstring_match, si}, + {"DIRECTORY", Ldirectory, cl}, + {"CHDIR", siLchdir, si}, + + /* unixsys.c */ + + {"SYSTEM", siLsystem, si}, + {"OPEN-PIPE", siLopen_pipe, si}, + + /* end of list */ + {NULL, NULL, 0} +}; + + +void +init_all_functions(void) { + const struct function_info *f = all_functions; + + for (f = all_functions; f->name != NULL; f++) { + switch (f->type) { + case cl: + make_function(f->name, f->f); + break; + case si: + make_si_function(f->name, f->f); + break; + case form: { + cl_object s = make_ordinary(f->name); + s->symbol.isform = TRUE; + s->symbol.mflag = FALSE; + } + } + } +} diff --git a/src/c/all_keywords.d b/src/c/all_keywords.d new file mode 100644 index 000000000..0b372df5b --- /dev/null +++ b/src/c/all_keywords.d @@ -0,0 +1,141 @@ +/* + all_keywords.d -- All named keywords. +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "page.h" + +const struct keyword_info all_keywords[] = { +/* bind.c */ +{&Kallow_other_keys, "ALLOW-OTHER-KEYS"}, + +/* error.c */ +{&Kpathname, "PATHNAME"}, +{&Kdatum, "DATUM"}, +{&Kexpected_type, "EXPECTED-TYPE"}, +{&Kformat_control, "FORMAT-CONTROL"}, +{&Kformat_arguments, "FORMAT-ARGUMENTS"}, + +/* file.c */ +{&Kerror, "ERROR"}, +{&Kabort, "ABORT"}, +{&Kdirection, "DIRECTION"}, +{&Kinput, "INPUT"}, +{&Koutput, "OUTPUT"}, +{&Kio, "IO"}, +{&Kprobe, "PROBE"}, +{&Kelement_type, "ELEMENT-TYPE"}, +{&Kdefault, "DEFAULT"}, +{&Kif_exists, "IF-EXISTS"}, +{&Knew_version, "NEW-VERSION"}, +{&Krename, "RENAME"}, +{&Krename_and_delete, "RENAME-AND-DELETE"}, +{&Koverwrite, "OVERWRITE"}, +{&Kappend, "APPEND"}, +{&Ksupersede, "SUPERSEDE"}, +{&Kcreate, "CREATE"}, +{&Kprint, "PRINT"}, +{&Kif_does_not_exist, "IF-DOES-NOT-EXIST"}, +{&Kset_default_pathname, "SET-DEFAULT-PATHNAME"}, + +/* hash.c */ +{&Ksize, "SIZE"}, +{&Krehash_size, "REHASH-SIZE"}, +{&Krehash_threshold, "REHASH-THRESHOLD"}, + +/* list.c */ +{&Ktest, "TEST"}, +{&Ktest_not, "TEST-NOT"}, +{&Kkey, "KEY"}, +{&Kinitial_element, "INITIAL-ELEMENT"}, + +/* load.c */ +{&Kverbose, "VERBOSE"}, + +/* package.c */ +{&Kinternal, "INTERNAL"}, +{&Kexternal, "EXTERNAL"}, +{&Kinherited, "INHERITED"}, +{&Knicknames, "NICKNAMES"}, +{&Kuse, "USE"}, + +/* pathname.c */ +{&Kwild, "WILD"}, +{&Kwild_inferiors, "WILD-INFERIORS"}, +{&Knewest, "NEWEST"}, +{&Khost, "HOST"}, +{&Kdevice, "DEVICE"}, +{&Kdirectory, "DIRECTORY"}, +{&Kname, "NAME"}, +{&Ktype, "TYPE"}, +{&Kversion, "VERSION"}, +{&Kdefaults, "DEFAULTS"}, +{&Kabsolute, "ABSOLUTE"}, +{&Krelative, "RELATIVE"}, +{&Kup, "UP"}, + +/* print.c */ +{&Kupcase, "UPCASE"}, +{&Kdowncase, "DOWNCASE"}, +{&Kcapitalize, "CAPITALIZE"}, +{&Kstream, "STREAM"}, +{&Kescape, "ESCAPE"}, +{&Kpretty, "PRETTY"}, +{&Kcircle, "CIRCLE"}, +{&Kbase, "BASE"}, +{&Kradix, "RADIX"}, +{&Kcase, "CASE"}, +{&Kgensym, "GENSYM"}, +{&Klevel, "LEVEL"}, +{&Klength, "LENGTH"}, +{&Karray, "ARRAY"}, + +/* read.c */ +{&Kjunk_allowed, "JUNK-ALLOWED"}, + +/* stacks.d */ +{&Kcatch, "CATCH"}, +{&Kcatchall, "CATCHALL"}, +{&Kprotect, "PROTECT"}, + +/* string.c */ +{&Kstart1, "START1"}, +{&Kend1, "END1"}, +{&Kstart2, "START2"}, +{&Kend2, "END2"}, +{&Kstart, "START"}, +{&Kend, "END"}, + +/* toplevel */ +{&Kexecute, "EXECUTE"}, +{&Kcompile_toplevel, "COMPILE-TOPLEVEL"}, +{&Kload_toplevel, "LOAD-TOPLEVEL"}, + +/* unixfsys.c */ +{&Klist_all, "LIST-ALL"}, + +/* END */ +{NULL, (const char*)NULL}}; + +void +init_all_keywords(void) +{ + const struct keyword_info *k = all_keywords; + cl_object *keyword_loc; + + while (k->name != NULL) { + keyword_loc = k->loc; + *keyword_loc = make_keyword(k->name); + k++; + } +} diff --git a/src/c/all_symbols.d b/src/c/all_symbols.d new file mode 100644 index 000000000..a3ba30ddf --- /dev/null +++ b/src/c/all_symbols.d @@ -0,0 +1,343 @@ +#include "ecls.h" +#include "page.h" + +const struct symbol_info all_symbols[] = { +/* assignment.c */ +{&Ssetf, "SETF", CL_ORDINARY}, +{&Spsetf, "PSETF", CL_ORDINARY}, +{&siSsetf_symbol, "SETF-SYMBOL", SI_ORDINARY}, +{&siSclear_compiler_properties, "CLEAR-COMPILER-PROPERTIES", SI_ORDINARY}, +#ifdef PDE +{&siVrecord_source_pathname_p, "*RECORD-SOURCE-PATHNAME-P*", SI_SPECIAL}, +{&siSrecord_source_pathname, "RECORD-SOURCE-PATHNAME", SI_ORDINARY}, +#endif + +/* backq.c */ +{&siScomma, ",", SI_ORDINARY}, +{&siScomma_at, ",@@", SI_ORDINARY}, +{&siScomma_dot, ",.", SI_ORDINARY}, +{&SlistX, "LIST*", CL_ORDINARY}, +{&Sappend, "APPEND", CL_ORDINARY}, +{&Snconc, "NCONC", CL_ORDINARY}, + +/* bind.c */ +{&SAoptional, "&OPTIONAL", CL_ORDINARY}, +{&SArest, "&REST", CL_ORDINARY}, +{&SAkey, "&KEY", CL_ORDINARY}, +{&SAallow_other_keys, "&ALLOW-OTHER-KEYS", CL_ORDINARY}, +{&SAaux, "&AUX", CL_ORDINARY}, + +/* block.c */ +{&Sblock, "BLOCK", CL_ORDINARY}, + +/* clos.c */ +#ifdef CLOS +{&siSXclass_name_hash_tableX, "*CLASS-NAME-HASH-TABLE*", SI_SPECIAL}, +{&Sclass, "CLASS", CL_ORDINARY}, +{&Sbuilt_in, "BUILT-IN", CL_ORDINARY}, +#endif + +/* compiler.c */ +{&siSlambda_block, "LAMBDA-BLOCK", CL_ORDINARY}, + +/* conditional.c */ +{&Sotherwise, "OTHERWISE", CL_ORDINARY}, + +/* error.c */ +{&Sarithmetic_error, "ARITHMETIC-ERROR", CL_ORDINARY}, +{&Scell_error, "CELL-ERROR", CL_ORDINARY}, +{&Scondition, "CONDITION", CL_ORDINARY}, +{&Sdivision_by_zero, "DIVISION-BY-ZERO", CL_ORDINARY}, +{&Send_of_file, "END-OF-FILE", CL_ORDINARY}, +{&Serror, "ERROR", CL_ORDINARY}, +{&Sfile_error, "FILE-ERROR", CL_ORDINARY}, +{&Sfloating_point_inexact, "FLOATING-POINT-INEXACT", CL_ORDINARY}, +{&Sfloating_point_invalid_operation, "FLOATING-POINT-INVALID-OPERATION", CL_ORDINARY}, +{&Sfloating_point_overflow, "FLOATING-POINT-OVERFLOW", CL_ORDINARY}, +{&Sfloating_point_underflow, "FLOATING-POINT-UNDERFLOW", CL_ORDINARY}, +{&Spackage_error, "PACKAGE-ERROR", CL_ORDINARY}, +{&Sparse_error, "PARSE-ERROR", CL_ORDINARY}, +{&Sprint_not_readable, "PRINT-NOT-READABLE", CL_ORDINARY}, +{&Sprogram_error, "PROGRAM-ERROR", CL_ORDINARY}, +{&Sreader_error, "READER-ERROR", CL_ORDINARY}, +{&Sserious_condition, "SERIOUS-CONDITION", CL_ORDINARY}, +{&Ssimple_condition, "SIMPLE-CONDITION", CL_ORDINARY}, +{&Ssimple_error, "SIMPLE-ERROR", CL_ORDINARY}, +{&Ssimple_type_error, "SIMPLE-TYPE-ERROR", CL_ORDINARY}, +{&Ssimple_warning, "SIMPLE-WARNING", CL_ORDINARY}, +{&Sstorage_condition, "STORAGE-CONDITION", CL_ORDINARY}, +{&Sstream_error, "STREAM-ERROR", CL_ORDINARY}, +{&Sstyle_warning, "STYLE-WARNING", CL_ORDINARY}, +{&Stype_error, "TYPE-ERROR", CL_ORDINARY}, +{&Sunbound_slot, "UNBOUND-SLOT", CL_ORDINARY}, +{&Sunbound_variable, "UNBOUND-VARIABLE", CL_ORDINARY}, +{&Sundefined_function, "UNDEFINED-FUNCTION", CL_ORDINARY}, +{&Swarning, "WARNING", CL_ORDINARY}, + +{&siSsimple_program_error, "SIMPLE-PROGRAM-ERROR", SI_ORDINARY}, +{&siSsimple_control_error, "SIMPLE-CONTROL-ERROR", SI_ORDINARY}, + +{&siSuniversal_error_handler, "UNIVERSAL-ERROR-HANDLER", SI_ORDINARY}, +{&siSterminal_interrupt, "TERMINAL-INTERRUPT", SI_ORDINARY}, + +/* eval.c */ +{&Sapply, "APPLY", CL_ORDINARY}, +{&Sfuncall, "FUNCALL", CL_ORDINARY}, +{&Vevalhook, "*EVALHOOK*", CL_SPECIAL}, +{&Vapplyhook, "*APPLYHOOK*", CL_SPECIAL}, + +/* file.c */ +{&Vstandard_input, "*STANDARD-INPUT*", CL_SPECIAL}, +{&Vstandard_output, "*STANDARD-OUTPUT*", CL_SPECIAL}, +{&Verror_output, "*ERROR-OUTPUT*", CL_SPECIAL}, +{&Vquery_io, "*QUERY-IO*", CL_SPECIAL}, +{&Vdebug_io, "*DEBUG-IO*", CL_SPECIAL}, +{&Vterminal_io, "*TERMINAL-IO*", CL_SPECIAL}, +{&Vtrace_output, "*TRACE-OUTPUT*", CL_SPECIAL}, +{&siVignore_eof_on_terminal_io, "*IGNORE-EOF-ON-TERMINAL-IO*", SI_SPECIAL}, + +/* format.c */ +{&siVindent_formatted_output, "*INDENT-FORMATTED-OUTPUT*", SI_SPECIAL}, + +/* gbc.c */ +#if 0 && !defined(GBC_BOEHM) +{&siVgc_verbose, "*GC-VERBOSE*", SI_SPECIAL}, +{&siVgc_message, "*GC-MESSAGE*", SI_SPECIAL}, +#endif /* !GBC_BOEHM */ + +/* gfun.c */ +{&siScompute_applicable_methods, "COMPUTE-APPLICABLE-METHODS", SI_ORDINARY}, +{&siScompute_effective_method, "COMPUTE-EFFECTIVE-METHOD", SI_ORDINARY}, +{&siSgeneric_function_method_combination, "GENERIC-FUNCTION-METHOD-COMBINATION", SI_ORDINARY}, +{&siSgeneric_function_method_combination_args, "GENERIC-FUNCTION-METHOD-COMBINATION-ARGS", SI_ORDINARY}, + +/* hash.c */ +{&Seq, "EQ", CL_ORDINARY}, +{&Seql, "EQL", CL_ORDINARY}, +{&Sequal, "EQUAL", CL_ORDINARY}, + +/* instance.c */ +{&Sprint_object, "PRINT-OBJECT", CL_ORDINARY}, + +/* lex.c */ +{&Smacro, "MACRO", CL_ORDINARY}, +{&siSsymbol_macro, "SYMBOL-MACRO", SI_ORDINARY}, +{&Stag, "TAG", CL_ORDINARY}, + +/* load.c */ +{&Vload_verbose, "*LOAD-VERBOSE*", CL_SPECIAL}, +{&Vload_print, "*LOAD-PRINT*", CL_SPECIAL}, +{&siVload_hooks, "*LOAD-HOOKS*", SI_SPECIAL}, +#ifdef PDE +{&siVsource_pathname, "*SOURCE-PATHNAME*", CL_SPECIAL}, +#endif +#ifdef RSYM +{&siVsymbol_table, "*SYMBOL-TABLE*", CL_SPECIAL}, +#endif + +/* lwp.c */ +#ifdef THREADS +{&Srunning, "RUNNING", CL_ORDINARY}, +{&Ssuspended, "SUSPENDED", CL_ORDINARY}, +{&Swaiting, "WAITING", CL_ORDINARY}, +{&Sstopped, "STOPPED", CL_ORDINARY}, +{&Sdead, "DEAD", CL_ORDINARY}, +{&siSthread_top_level, "THREAD-TOP-LEVEL", SI_ORDINARY}, +#endif + +/* macros.c */ +{&Vmacroexpand_hook, "*MACROEXPAND-HOOK*", CL_SPECIAL}, +{&siSexpand_defmacro, "EXPAND-DEFMACRO", SI_ORDINARY}, +{&siVinhibit_macro_special, "*INHIBIT-MACRO-SPECIAL*", SI_SPECIAL}, + +/* main.c */ +{&siVsystem_directory, "*SYSTEM-DIRECTORY*", SI_SPECIAL}, +{&Vfeatures, "*FEATURES*", CL_SPECIAL}, + +/* num_rand.c */ +{&Vrandom_state, "*RANDOM-STATE*", CL_SPECIAL}, + +/* package.c */ +{&Vpackage, "*PACKAGE*", CL_SPECIAL}, + +/* pathname.c */ +{&Vdefault_pathname_defaults, "*DEFAULT-PATHNAME-DEFAULTS*", CL_SPECIAL}, + +/* print.c */ +{&Vprint_escape, "*PRINT-ESCAPE*", CL_SPECIAL}, +{&Vprint_pretty, "*PRINT-PRETTY*", CL_SPECIAL}, +{&Vprint_circle, "*PRINT-CIRCLE*", CL_SPECIAL}, +{&Vprint_base, "*PRINT-BASE*", CL_SPECIAL}, +{&Vprint_radix, "*PRINT-RADIX*", CL_SPECIAL}, +{&Vprint_case, "*PRINT-CASE*", CL_SPECIAL}, +{&Vprint_gensym, "*PRINT-GENSYM*", CL_SPECIAL}, +{&Vprint_level, "*PRINT-LEVEL*", CL_SPECIAL}, +{&Vprint_length, "*PRINT-LENGTH*", CL_SPECIAL}, +{&Vprint_array, "*PRINT-ARRAY*", CL_SPECIAL}, +{&siSpretty_print_format, "PRETTY-PRINT-FORMAT", SI_ORDINARY}, +{&siSsharp_exclamation, "#!", SI_ORDINARY}, +{&siVprint_package, "*PRINT-PACKAGE*", SI_SPECIAL}, +{&siVprint_structure, "*PRINT-STRUCTURE*", SI_SPECIAL}, +#ifdef CLOS +{&Sstream_write_char, "STREAM-WRITE-CHAR", CL_ORDINARY}, +{&Sstream_write_string, "STREAM-WRITE-STRING", CL_ORDINARY}, +{&Sstream_fresh_line, "STREAM-FRESH-LINE", CL_ORDINARY}, +{&Sstream_clear_output, "STREAM-CLEAR-OUTPUT", CL_ORDINARY}, +{&Sstream_force_output, "STREAM-FORCE-OUTPUT", CL_ORDINARY}, +#endif + +/* profile.c */ +#ifdef PROFILE +{&sSAprofile_arrayA, "*PROFILE-ARRAY*", SI_SPECIAL}, +#endif PROFILE + +/* read.c */ +{&Vreadtable, "*READTABLE*", CL_SPECIAL}, +{&Vread_default_float_format, "*READ-DEFAULT-FLOAT-FORMAT*", CL_SPECIAL}, +{&Vread_base, "*READ-BASE*", CL_SPECIAL}, +{&Vread_suppress, "*READ-SUPPRESS*", CL_SPECIAL}, +{&siSsharp_comma, "#,", SI_ORDINARY}, +#ifdef CLOS +{&Sstream_read_line, "STREAM-READ-LINE", CL_ORDINARY}, +{&Sstream_read_char, "STREAM-READ-CHAR", CL_ORDINARY}, +{&Sstream_unread_char, "STREAM-UNREAD-CHAR", CL_ORDINARY}, +{&Sstream_peek_char, "STREAM-PEEK-CHAR", CL_ORDINARY}, +{&Sstream_listen, "STREAM-LISTEN", CL_ORDINARY}, +{&Sstream_clear_input, "STREAM-CLEAR-INPUT", CL_ORDINARY}, +#endif + +/* structure.c */ +{&siSstructure_print_function, "STRUCTURE-PRINT-FUNCTION", SI_ORDINARY}, +{&siSstructure_slot_descriptions, "STRUCTURE-SLOT-DESCRIPTIONS", SI_ORDINARY}, +#ifndef CLOS +{&siSstructure_include, "STRUCTURE-INCLUDE", SI_ORDINARY}, +#else +{&Sstructure_object, "STRUCTURE-OBJECT", CL_ORDINARY}, +#endif + +/* symbol.c */ +{&siSpname, "PNAME", SI_ORDINARY}, +{&Vgensym_counter, "*GENSYM-COUNTER*", CL_SPECIAL}, + +/* toplevel.c */ +{&Sdeclare, "DECLARE", CL_ORDINARY}, +{&Scompile, "COMPILE", CL_ORDINARY}, +{&Sload, "LOAD", CL_ORDINARY}, +{&Seval, "EVAL", CL_ORDINARY}, +{&Sprogn, "PROGN", CL_ORDINARY}, +{&Swarn, "WARN", CL_ORDINARY}, +{&Stypep, "TYPEP", CL_ORDINARY}, + +/* typespec.c */ +{&Squote, "QUOTE", CL_ORDINARY}, +{&Slambda, "LAMBDA", CL_ORDINARY}, +{&Sspecial, "SPECIAL", CL_ORDINARY}, +{&St, "T", CL_ORDINARY}, +{&Snil, "NIL", CL_ORDINARY}, +{&Scommon, "COMMON", CL_ORDINARY}, +{&Ssequence, "SEQUENCE", CL_ORDINARY}, +{&Snull, "NULL", CL_ORDINARY}, +{&Scons, "CONS", CL_ORDINARY}, +{&Slist, "LIST", CL_ORDINARY}, +{&Ssymbol, "SYMBOL", CL_ORDINARY}, +{&Sarray, "ARRAY", CL_ORDINARY}, +{&Svector, "VECTOR", CL_ORDINARY}, +{&Sbit_vector, "BIT-VECTOR", CL_ORDINARY}, +{&Sstring, "STRING", CL_ORDINARY}, +{&Ssimple_array, "SIMPLE-ARRAY", CL_ORDINARY}, +{&Ssimple_vector, "SIMPLE-VECTOR", CL_ORDINARY}, +{&Ssimple_string, "SIMPLE-STRING", CL_ORDINARY}, +{&Ssimple_bit_vector, "SIMPLE-BIT-VECTOR", CL_ORDINARY}, +{&Sfunction, "FUNCTION", CL_ORDINARY}, +{&Spathname, "PATHNAME", CL_ORDINARY}, +{&Slogical_pathname, "LOGICAL-PATHNAME", CL_ORDINARY}, +{&Scharacter, "CHARACTER", CL_ORDINARY}, +{&Sbase_char, "BASE-CHAR", CL_ORDINARY}, +{&Sextended_char, "EXTENDED-CHAR", CL_ORDINARY}, +{&Scompiled_function, "COMPILED-FUNCTION", CL_ORDINARY}, +{&Snumber, "NUMBER", CL_ORDINARY}, +{&Sreal, "REAL", CL_ORDINARY}, +{&Srational, "RATIONAL", CL_ORDINARY}, +{&Sfloat, "FLOAT", CL_ORDINARY}, +{&Sinteger, "INTEGER", CL_ORDINARY}, +{&Sratio, "RATIO", CL_ORDINARY}, +{&Sshort_float, "SHORT-FLOAT", CL_ORDINARY}, +{&Sstandard_char, "STANDARD-CHAR", CL_ORDINARY}, +{&Sfixnum, "FIXNUM", CL_ORDINARY}, +{&Scomplex, "COMPLEX", CL_ORDINARY}, +{&Ssingle_float, "SINGLE-FLOAT", CL_ORDINARY}, +{&Spackage, "PACKAGE", CL_ORDINARY}, +{&Sbignum, "BIGNUM", CL_ORDINARY}, +{&Srandom_state, "RANDOM-STATE", CL_ORDINARY}, +{&Sdouble_float, "DOUBLE-FLOAT", CL_ORDINARY}, +{&Sstream, "STREAM", CL_ORDINARY}, +{&Sbit, "BIT", CL_ORDINARY}, +{&Sreadtable, "READTABLE", CL_ORDINARY}, +{&Slong_float, "LONG-FLOAT", CL_ORDINARY}, +{&Shash_table, "HASH-TABLE", CL_ORDINARY}, +{&Ssigned_char, "SIGNED-CHAR", CL_ORDINARY}, +{&Sunsigned_char, "UNSIGNED-CHAR", CL_ORDINARY}, +{&Ssigned_short, "SIGNED-SHORT", CL_ORDINARY}, +{&Sunsigned_short, "UNSIGNED-SHORT", CL_ORDINARY}, +#ifdef CLOS +{&Sinstance, "INSTANCE", CL_ORDINARY}, +{&Sdispatch_function, "DISPATCH-FUNCTION", CL_ORDINARY}, +{&Sstructure, "STRUCTURE", CL_ORDINARY}, +#endif +{&Ssatisfies, "SATISFIES", CL_ORDINARY}, +{&Smember, "MEMBER", CL_ORDINARY}, +{&Snot, "NOT", CL_ORDINARY}, +{&Sor, "OR", CL_ORDINARY}, +{&Sand, "AND", CL_ORDINARY}, +{&Svalues, "VALUES", CL_ORDINARY}, +{&Smod, "MOD", CL_ORDINARY}, +{&Ssigned_byte, "SIGNED-BYTE", CL_ORDINARY}, +{&Sunsigned_byte, "UNSIGNED-BYTE", CL_ORDINARY}, +{&SX, "*", CL_ORDINARY}, +{&Splusp, "PLUSP", CL_ORDINARY}, +{&Skeyword, "KEYWORD", CL_ORDINARY}, +#ifdef THREADS +{&Scont, "CONT", CL_ORDINARY}, +{&Sthread, "THREAD", CL_ORDINARY}, +#endif +#ifdef LOCATIVE +{&Slocative, "LOCATIVE", CL_ORDINARY}, +#endif +{&Ssubtypep, "SUBTYPEP", CL_ORDINARY}, + +/* unify.c */ +#ifdef LOCATIVE +{&Ssetq, "SETQ", CL_ORDINARY}, +{&Sunify_slot, "UNIFY-SLOT", CL_ORDINARY}, +#endif + +{NULL, (const char*)NULL, CL_ORDINARY}}; + +void +init_all_symbols(void) { + const struct symbol_info *s = all_symbols; + cl_object *loc; + + /* This must keep the garbage collector happy */ + for (s = all_symbols; s->name != NULL; s++) + *(s->loc) = OBJNULL; + + for (s = all_symbols; s->name != NULL; s++) { + loc = s->loc; + switch (s->type) { + case CL_ORDINARY: + *loc = make_ordinary(s->name); + break; + case CL_SPECIAL: + *loc = make_special(s->name, Cnil); + break; + case SI_ORDINARY: + *loc = make_si_ordinary(s->name); + break; + case SI_SPECIAL: + *loc = make_si_special(s->name, Cnil); + break; + } + /* register_root(loc);*/ + } +} diff --git a/src/c/alloc.d b/src/c/alloc.d new file mode 100644 index 000000000..dff8f61bb --- /dev/null +++ b/src/c/alloc.d @@ -0,0 +1,900 @@ + +/* + alloc.c -- Memory allocation. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +/* + Heap and Relocatable Area + + heap_end data_end + +------+--------------------+ - - - + - - --------+ + | text | heap | hole | stack | + +------+--------------------+ - - - + - - --------+ + + The type_map array covers all pages of memory: those not used for objects + are marked as type t_other. + + The tm_table array holds a struct typemanager for each type, which contains + the first element of the free list for the type, and other bookkeeping + information. +*/ + +#include "ecls.h" +#include "page.h" +#ifdef BSD +#include +#endif BSD +#ifdef SYSV +#include +#endif SYSV + +/******************************* EXPORTS ******************************/ + +size_t real_maxpage; +size_t new_holepage; +char type_map[MAXPAGE]; +struct typemanager tm_table[(int)t_end]; +struct contblock *cb_pointer = NULL; + +size_t ncb; /* number of contblocks */ +size_t ncbpage; /* number of contblock pages */ +size_t maxcbpage; /* maximum number of contblock pages */ +size_t cbgccount; /* contblock gc count */ +size_t holepage; /* hole pages */ + +char *heap_end; /* heap end */ +char *heap_start; /* heap start */ +char *data_end; /* end of data space */ + +/******************************* ------- ******************************/ + +#define SIGINTENTRY 6 + +static bool ignore_maximum_pages = TRUE; + +#ifdef unix +# ifdef __MACH__ +# define sbrk my_sbrk +# endif +extern void *sbrk(int); +#endif unix + +#ifdef NEED_MALLOC +static cl_object malloc_list; +#endif + +/* + Allocates n pages starting at heap end, without worring about the + hole. Basically just get the space from the Operating System. +*/ + +void +resize_hole(size_t n) +{ + char *e; + size_t m; + m = (data_end - heap_end)/LISP_PAGESIZE; + if (n <= m) + return; + + /* Create the hole */ +#ifdef unix + e = sbrk(0); + if (data_end == e) + n -= m; + else { + dealloc(heap_end, data_end - heap_end); + /* FIXME! Horrible hack! */ + /* mark as t_other pages not allocated by us */ + heap_end = e; + while (data_end < heap_end) { + type_map[page(data_end)] = t_other; + data_end += LISP_PAGESIZE; + } + holepage = 0; + } + if ((int)sbrk(LISP_PAGESIZE * n) < 0) + error("Can't allocate. Good-bye!"); +#endif unix + data_end += LISP_PAGESIZE*(n); + holepage += n; +} + +/* Allocates n pages from the hole. */ +void * +alloc_page(size_t n) +{ + char *e = heap_end; + if (n >= holepage) { + gc(t_contiguous); + resize_hole(new_holepage+n); + } + holepage -= n; + heap_end += LISP_PAGESIZE*n; + return e; +} + +static void +add_page_to_freelist(char *p, struct typemanager *tm) +{ enum type t; + cl_object x, f; + size_t i; + t = tm->tm_type; + type_map[page(p)] = t; + f = tm->tm_free; + for (i = tm->tm_nppage; i > 0; --i, p += tm->tm_size) { + x = (cl_object)p; + ((struct freelist *)x)->t = (short)t; + ((struct freelist *)x)->m = FREE; + ((struct freelist *)x)->f_link = f; + f = x; + } + tm->tm_free = f; + tm->tm_nfree += tm->tm_nppage; + tm->tm_npage++; +} + +cl_object +alloc_object(enum type t) +{ + register cl_object obj; + register struct typemanager *tm; + register char *p; + + switch (t) { + case t_fixnum: + return MAKE_FIXNUM(0); /* Immediate fixnum */ + case t_character: + return code_char(' '); /* Immediate character */ + default: + } + + start_critical_section(); + +ONCE_MORE: + tm = tm_of(t); + + if (interrupt_flag) { + interrupt_flag = FALSE; +#ifdef unix + alarm(0); +#endif unix + terminal_interrupt(TRUE); + } + + obj = tm->tm_free; + if (obj == OBJNULL) { + size_t available = available_pages(); + if (tm->tm_npage >= tm->tm_maxpage) + goto CALL_GC; + if (available < 1) { + ignore_maximum_pages = FALSE; + goto CALL_GC; + } + p = alloc_page(1); + add_page_to_freelist(p, tm); + obj = tm->tm_free; + /* why this? Beppe + if (tm->tm_npage >= tm->tm_maxpage) + goto CALL_GC; */ + } + tm->tm_free = ((struct freelist *)obj)->f_link; + --(tm->tm_nfree); + (tm->tm_nused)++; + obj->d.t = (short)t; + obj->d.m = FALSE; + /* Now initialize the object so that it can be correctly marked + * by the GC + */ + switch (t) { + case t_bignum: + obj->big.big_dim = obj->big.big_size = 0; + obj->big.big_limbs = NULL; + break; + case t_ratio: + obj->ratio.num = OBJNULL; + obj->ratio.den = OBJNULL; + break; + case t_shortfloat: + case t_longfloat: + break; + case t_complex: + obj->complex.imag = OBJNULL; + obj->complex.real = OBJNULL; + break; + case t_symbol: + obj->symbol.plist = OBJNULL; + SYM_FUN(obj) = OBJNULL; + SYM_VAL(obj) = OBJNULL; + obj->symbol.name = OBJNULL; + break; + case t_package: + obj->pack.name = OBJNULL; + obj->pack.nicknames = OBJNULL; + obj->pack.shadowings = OBJNULL; + obj->pack.uses = OBJNULL; + obj->pack.usedby = OBJNULL; + obj->pack.internal = OBJNULL; + obj->pack.external = OBJNULL; + break; + case t_cons: + CAR(obj) = OBJNULL; + CDR(obj) = OBJNULL; + break; + case t_hashtable: + obj->hash.rehash_size = OBJNULL; + obj->hash.threshold = OBJNULL; + obj->hash.data = NULL; + break; + case t_array: + obj->array.displaced = Cnil; + obj->array.elttype = (short)aet_object; + obj->array.self.t = NULL; + break; + case t_vector: + obj->array.displaced = Cnil; + obj->array.elttype = (short)aet_object; + obj->array.self.t = NULL; + break; + case t_string: + obj->string.displaced = Cnil; + obj->string.self = NULL; + break; + case t_bitvector: + obj->vector.displaced = Cnil; + obj->vector.self.bit = NULL; + break; +#ifndef CLOS + case t_structure: + obj->str.name = OBJNULL; + obj->str.self = NULL; + break; +#endif CLOS + case t_stream: + obj->stream.mode = (short)smm_closed; + obj->stream.file = NULL; + obj->stream.object0 = OBJNULL; + obj->stream.object1 = OBJNULL; + obj->stream.buffer = NULL; + break; + case t_random: + break; + case t_readtable: + obj->readtable.table = NULL; + break; + case t_pathname: + obj->pathname.host = OBJNULL; + obj->pathname.device = OBJNULL; + obj->pathname.directory = OBJNULL; + obj->pathname.name = OBJNULL; + obj->pathname.type = OBJNULL; + obj->pathname.version = OBJNULL; + break; + case t_bytecodes: + obj->bytecodes.lex = Cnil; + obj->bytecodes.size = 0; + obj->bytecodes.data = NULL; + break; + case t_cfun: + obj->cfun.name = OBJNULL; + obj->cfun.block = NULL; + break; + case t_cclosure: + obj->cclosure.env = OBJNULL; + obj->cclosure.block = NULL; + break; +/* + case t_spice: + break; +*/ +#ifdef THREADS + case t_cont: + obj->cn.cn_thread = OBJNULL; + break; + case t_thread: + obj->thread.entry = OBJNULL; + break; +#endif +#ifdef CLOS + case t_instance: + obj->instance.class = OBJNULL; + obj->instance.slots = NULL; + break; + case t_gfun: + obj->gfun.name = OBJNULL; + obj->gfun.method_hash = OBJNULL; + obj->gfun.instance = OBJNULL; + obj->gfun.specializers = NULL; + break; +#endif CLOS + case t_codeblock: + obj->cblock.name = Cnil; + obj->cblock.start = NULL; + obj->cblock.size = 0; + obj->cblock.data = NULL; + obj->cblock.data_size = 0; + obj->cblock.data_text = NULL; + obj->cblock.data_text_size = 0; + break; + default: + printf("\ttype = %d\n", t); + error("alloc botch."); + } +#ifdef THREADS + clwp->lwp_alloc_temporary = obj; +#endif THREADS + end_critical_section(); + return(obj); + +CALL_GC: + gc(tm->tm_type); + if (tm->tm_nfree != 0 && + (float)tm->tm_nfree * 10.0 >= (float)tm->tm_nused) + goto ONCE_MORE; + +/* EXHAUSTED: */ + if (ignore_maximum_pages) { + if (tm->tm_maxpage/2 <= 0) + tm->tm_maxpage += 1; + else + tm->tm_maxpage += tm->tm_maxpage/2; + goto ONCE_MORE; + } + GC_disable(); + { cl_object s = make_simple_string(tm_table[(int)t].tm_name+1); + GC_enable(); + CEerror("The storage for ~A is exhausted.~%\ +Currently, ~D pages are allocated.~%\ +Use ALLOCATE to expand the space.", + 2, s, MAKE_FIXNUM(tm->tm_npage)); + } + goto ONCE_MORE; +} + +cl_object +make_cons(cl_object a, cl_object d) +{ + register cl_object obj; + register char *p; + struct typemanager *tm=(&tm_table[(int)t_cons]); + + start_critical_section(); + +ONCE_MORE: + if (interrupt_flag) { + interrupt_flag = FALSE; +#ifdef unix + alarm(0); +#endif unix + terminal_interrupt(TRUE); + } + obj = tm->tm_free; + if (obj == OBJNULL) { + if (tm->tm_npage >= tm->tm_maxpage) + goto CALL_GC; + if (available_pages() < 1) { + ignore_maximum_pages = FALSE; + goto CALL_GC; + } + p = alloc_page(1); + add_page_to_freelist(p,tm); + obj = tm->tm_free; + if (tm->tm_npage >= tm->tm_maxpage) + goto CALL_GC; + } + tm->tm_free = ((struct freelist *)obj)->f_link; + --(tm->tm_nfree); + (tm->tm_nused)++; + obj->d.t = (short)t_cons; + obj->d.m = FALSE; + CAR(obj) = a; + CDR(obj) = d; + + end_critical_section(); + return(obj); + +CALL_GC: + gc(t_cons); + if ((tm->tm_nfree != 0) && (tm->tm_nfree * 10.0 >= tm->tm_nused)) + goto ONCE_MORE; + +/* EXHAUSTED: */ + if (ignore_maximum_pages) { + if (tm->tm_maxpage/2 <= 0) + tm->tm_maxpage += 1; + else + tm->tm_maxpage += tm->tm_maxpage/2; + goto ONCE_MORE; + } + CEerror("The storage for CONS is exhausted.~%\ +Currently, ~D pages are allocated.~%\ +Use ALLOCATE to expand the space.", + 1, MAKE_FIXNUM(tm->tm_npage)); + goto ONCE_MORE; +#undef tm +} + +cl_object +alloc_instance(cl_index slots) +{ + cl_object i = alloc_object(t_instance); + /* INV: slots > 0 */ + i->instance.slots = alloc(sizeof(cl_object) * slots); + i->instance.length = slots; + return i; +} + +void * +alloc(size_t n) +{ + register char *p; + register struct contblock **cbpp; + register size_t i; + register size_t m; + register bool g; + bool gg; + + g = FALSE; + n = round_up(n); + + start_critical_section(); + +ONCE_MORE: + if (interrupt_flag) { + interrupt_flag = FALSE; + gg = g; + terminal_interrupt(TRUE); + g = gg; + } + + /* Use extra indirection so that cb_pointer can be updated */ + for (cbpp = &cb_pointer; (*cbpp) != NULL; cbpp = &(*cbpp)->cb_link) + if ((*cbpp)->cb_size >= n) { + p = (char *)(*cbpp); + i = (*cbpp)->cb_size - n; + *cbpp = (*cbpp)->cb_link; + --ncb; + dealloc(p+n, i); + + end_critical_section(); + return(p); + } + m = round_to_page(n); + if (ncbpage + m > maxcbpage || available_pages() < m) { + if (available_pages() < m) + ignore_maximum_pages = FALSE; + if (!g) { + gc(t_contiguous); + g = TRUE; + goto ONCE_MORE; + } + if (ignore_maximum_pages) { + if (maxcbpage/2 <= 0) + maxcbpage += 1; + else + maxcbpage += maxcbpage/2; + g = FALSE; + goto ONCE_MORE; + } + CEerror("Contiguous blocks exhausted.~%\ +Currently, ~D pages are allocated.~%\ +Use ALLOCATE-CONTIGUOUS-PAGES to expand the space.", + 1, MAKE_FIXNUM(ncbpage)); + g = FALSE; + goto ONCE_MORE; + } + p = alloc_page(m); + + for (i = 0; i < m; i++) + type_map[page(p) + i] = (char)t_contiguous; + ncbpage += m; + dealloc(p+n, LISP_PAGESIZE*m - n); + + end_critical_section(); + return(p); +} + +/* + * adds a contblock to the list of available ones, pointed by cb_pointer, + * sorted by increasing size. + */ +void +dealloc(void *p, size_t s) +{ + struct contblock **cbpp, *cbp; + + if (s < CBMINSIZE) + return; + ncb++; + cbp = (struct contblock *)p; + cbp->cb_size = s; + for (cbpp = &cb_pointer; *cbpp != NULL; cbpp = &((*cbpp)->cb_link)) + if ((*cbpp)->cb_size >= s) { + cbp->cb_link = *cbpp; + *cbpp = cbp; + return; + } + cbp->cb_link = NULL; + *cbpp = cbp; +} + +/* + * align must be a power of 2 representing the alignment boundary + * required for the block. + */ +void * +alloc_align(size_t size, size_t align) +{ + void *output; + start_critical_section(); + align--; + output = (void*)(((cl_fixnum)alloc(size + align) + align - 1) & ~align) + end_critical_section(); + return output; +} + +static void +init_tm(enum type t, char *name, size_t elsize, size_t maxpage) +{ + int i, j; + struct typemanager *tm = &tm_table[(int)t]; + + tm->tm_name = name; + for (i = (int)t_start, j = i-1; i < (int)t_end; i++) + if (tm_table[i].tm_size >= elsize && + (j < (int)t_start || tm_table[j].tm_size > tm_table[i].tm_size)) + j = i; + if (j >= (int)t_start) { + tm->tm_type = (enum type)j; + tm_table[j].tm_maxpage += maxpage; + return; + } + tm->tm_type = t; + tm->tm_size = round_up(elsize); + tm->tm_nppage = LISP_PAGESIZE/round_up(elsize); + tm->tm_free = OBJNULL; + tm->tm_nfree = 0; + tm->tm_nused = 0; + tm->tm_npage = 0; + tm->tm_maxpage = maxpage; + tm->tm_gccount = 0; +} + +static int alloc_initialized = FALSE; + +void +init_alloc(void) +{ + cl_index i; + + if (alloc_initialized) return; + alloc_initialized = TRUE; + + holepage = 0; + new_holepage = HOLEPAGE; + +#ifdef MSDOS + real_maxpage = MAXPAGE; +#elif defined(BSD) + { + struct rlimit data_rlimit; +# ifdef __MACH__ + extern int mach_maplimit; + sbrk(0); + real_maxpage = mach_maplimit/LISP_PAGESIZE; + /* alternative + getrlimit(RLIMIT_DATA, &data_rlimit); + real_maxpage = ((unsigned)get_etext() + + (unsigned)data_rlimit.rlim_cur)/LISP_PAGESIZE; + */ +# else + extern etext; + + getrlimit(RLIMIT_DATA, &data_rlimit); + real_maxpage = ((unsigned int)&etext + + (unsigned)data_rlimit.rlim_cur)/LISP_PAGESIZE; +# endif + if (real_maxpage > MAXPAGE) real_maxpage = MAXPAGE; + } +#elif defined(SYSV) + real_maxpage= ulimit(UL_GMEMLIM)/LISP_PAGESIZE; + if (real_maxpage > MAXPAGE) real_maxpage = MAXPAGE; +#endif MSDOS + +#ifdef unix + heap_end = sbrk(0); + i = (int)heap_end & (LISP_PAGESIZE - 1); + if (i) + sbrk(LISP_PAGESIZE - i); + heap_end = heap_start = data_end = sbrk(0); +#else +#error "Non unix allocation scheme not defined" +#endif unix + + resize_hole(INIT_HOLEPAGE); + for (i = 0; i < MAXPAGE; i++) + type_map[i] = (char)t_other; + +/* Initialization must be done in increasing size order: */ + init_tm(t_shortfloat, "FSHORT-FLOAT", /* 8 */ + sizeof(struct shortfloat_struct), 1); + init_tm(t_cons, ".CONS", sizeof(struct cons), 384); /* 12 */ + init_tm(t_longfloat, "LLONG-FLOAT", /* 16 */ + sizeof(struct longfloat_struct), 1); + init_tm(t_bytecodes, "bBYTECODES", sizeof(struct bytecodes), 64); + init_tm(t_string, "\"STRING", sizeof(struct string), 64); /* 20 */ + init_tm(t_array, "aARRAY", sizeof(struct array), 64); /* 24 */ + init_tm(t_pathname, "pPATHNAME", sizeof(struct pathname), 1); /* 28 */ + init_tm(t_symbol, "|SYMBOL", sizeof(struct symbol), 64); /* 32 */ + init_tm(t_package, ":PACKAGE", sizeof(struct package), 1); /* 36 */ + init_tm(t_codeblock, "#CODEBLOCK", sizeof(struct codeblock), 1); + init_tm(t_bignum, "BBIGNUM", sizeof(struct bignum), 16); + init_tm(t_ratio, "RRATIO", sizeof(struct ratio), 1); + init_tm(t_complex, "CCOMPLEX", sizeof(struct complex), 1); + init_tm(t_hashtable, "hHASH-TABLE", sizeof(struct hashtable), 1); + init_tm(t_vector, "vVECTOR", sizeof(struct vector), 2); + init_tm(t_bitvector, "bBIT-VECTOR", sizeof(struct vector), 1); + init_tm(t_stream, "sSTREAM", sizeof(struct stream), 1); + init_tm(t_random, "$RANDOM-STATE", sizeof(struct random), 1); + init_tm(t_readtable, "rREADTABLE", sizeof(struct readtable), 1); + init_tm(t_cfun, "fCFUN", sizeof(struct cfun), 32); + init_tm(t_cclosure, "cCCLOSURE", sizeof(struct cclosure), 1); +#ifndef CLOS + init_tm(t_structure, "SSTRUCTURE", sizeof(struct structure), 32); +#else + init_tm(t_instance, "IINSTANCE", sizeof(struct instance), 32); + init_tm(t_gfun, "GGFUN", sizeof(struct gfun), 32); +#endif CLOS +#ifdef THREADS + init_tm(t_cont, "?CONT", sizeof(struct cont), 2); + init_tm(t_thread, "tTHREAD", sizeof(struct thread), 2); +#endif THREADS + + ncb = 0; + ncbpage = 0; +#ifdef THREADS + maxcbpage = 2048; +#else + maxcbpage = 512; +#endif THREADS + +#ifdef NEED_MALLOC + malloc_list = Cnil; + register_root(&malloc_list); +#endif +} + +static int +t_from_type(cl_object type) +{ int t; + + type = coerce_to_string(type); + for (t = (int)t_start ; t < (int)t_end ; t++) { + struct typemanager *tm = &tm_table[t]; + if (tm->tm_name && + strncmp((tm->tm_name)+1, type->string.self, type->string.fillp) == 0) + return(t); + } + FEerror("Unrecognized type", 0); +} + +@(defun si::allocate (type qty &optional (now Cnil)) + struct typemanager *tm; + char *pp; + size_t i; +@ + tm = tm_of(t_from_type(type)); + i = fixnnint(qty); + if (tm->tm_npage > i) i = tm->tm_npage; + tm->tm_maxpage = i; + if (now == Cnil || tm->tm_maxpage <= tm->tm_npage) + @(return Ct) + if (available_pages() < tm->tm_maxpage - tm->tm_npage || + (pp = alloc_page(tm->tm_maxpage - tm->tm_npage)) == NULL) + FEerror("Can't allocate ~D pages for ~A.", 2, type, + make_simple_string(tm->tm_name+1)); + for (; tm->tm_npage < tm->tm_maxpage; pp += LISP_PAGESIZE) + add_page_to_freelist(pp, tm); + @(return Ct) +@) + +@(defun si::maxpage (type) +@ + @(return MAKE_FIXNUM(tm_of(t_from_type(type))->tm_maxpage)) +@) + +@(defun si::allocated_pages (type) +@ + @(return MAKE_FIXNUM(tm_of(t_from_type(type))->tm_npage)) +@) + +@(defun si::alloc_contpage (qty &optional (now Cnil)) + size_t i, m; + char *p; +@ + i = fixnnint(qty); + if (ncbpage > i) + FEerror("Can't set the limit for contiguous blocks to ~D,~%\ +since ~D pages are already allocated.", + 2, qty, MAKE_FIXNUM(ncbpage)); + maxcbpage = i; + if (Null(now)) + @(return Ct) + m = maxcbpage - ncbpage; + if (available_pages() < m || (p = alloc_page(m)) == NULL) + FEerror("Can't allocate ~D pages for contiguous blocks.", + 1, qty); + for (i = 0; i < m; i++) + type_map[page(p + LISP_PAGESIZE*i)] = (char)t_contiguous; + ncbpage += m; + dealloc(p, LISP_PAGESIZE*m); + @(return Ct) +@) + +@(defun si::ncbpage () +@ + @(return MAKE_FIXNUM(ncbpage)) +@) + +@(defun si::maxcbpage () +@ + @(return MAKE_FIXNUM(maxcbpage)) +@) + +@(defun si::get_hole_size () +@ + @(return MAKE_FIXNUM(new_holepage)) +@) + +@(defun si::set_hole_size (size) + size_t i; +@ + i = fixnnint(size); + if (i == 0 || i > available_pages() + new_holepage) + FEerror("Illegal value for the hole size.", 0); + new_holepage = i; + @(return size) +@) + +@(defun si::ignore_maximum_pages (&optional (flag OBJNULL)) +@ + if (flag == OBJNULL) + @(return (ignore_maximum_pages? Ct : Cnil)) + ignore_maximum_pages = Null(flag); + @(return flag) +@) + +static cl_object siVlisp_maxpages, siClisp_pagesize; + +void +init_alloc_function(void) +{ + ignore_maximum_pages = TRUE; + siVlisp_maxpages = make_si_special("*LISP-MAXPAGES*", MAKE_FIXNUM(real_maxpage)); + siClisp_pagesize = make_si_constant("LISP-PAGESIZE", MAKE_FIXNUM(LISP_PAGESIZE)); + SYM_VAL(siVlisp_maxpages) = MAKE_FIXNUM(real_maxpage); +} + +#ifdef NEED_MALLOC +/* + UNIX malloc simulator. + + Used by + getwd, popen, etc. +*/ + +#undef malloc +#undef calloc +#undef free +#undef cfree +#undef realloc + +void * +malloc(size_t size) +{ + cl_object x; + +#ifdef __GNUC__ + if (!GC_enabled() && !alloc_initialized) + init_alloc(); +#endif __GNUC__ + + x = alloc_simple_string(size-1); + x->string.self = alloc(size); + malloc_list = make_cons(x, malloc_list); + return(x->string.self); +} + +void +free(void *ptr) +{ + cl_object *p; + + if (ptr) { + for (p = &malloc_list; !endp(*p); p = &(CDR((*p)))) + if ((CAR((*p)))->string.self == ptr) { + dealloc(CAR((*p))->string.self, CAR((*p))->string.dim); + CAR((*p))->string.self = NULL; + *p = CDR((*p)); + return; + } + FEerror("free(3) error.", 0); + } +} + +void * +realloc(void *ptr, size_t size) +{ + cl_object x; + size_t i, j; + + for (x = malloc_list; !endp(x); x = CDR(x)) + if (CAR(x)->string.self == ptr) { + x = CAR(x); + if (x->string.dim >= size) { + x->string.fillp = size; + return(ptr); + } else { + j = x->string.dim; + x->string.self = alloc(size); + x->string.fillp = x->string.dim = size; + memcpy(x->string.self, ptr, j); + dealloc(ptr, j); + return(x->string.self); + } + } + FEerror("realloc(3) error.", 0); +} + +void * +calloc(size_t nelem, size_t elsize) +{ + char *ptr; + size_t i = nelem*elsize; + ptr = malloc(i); + memset(ptr, 0 , i); + return(ptr); +} + +void cfree(void *ptr) +{ + free(ptr); +} + +/* make f allocate enough extra, so that we can round + up, the address given to an even multiple. Special + case of size == 0 , in which case we just want an aligned + number in the address range + */ + +#define ALLOC_ALIGNED(f, size, align) \ + ((align) <= 4 ? (int)(f)(size) : \ + ((align) * (((unsigned)(f)(size + (size ? (align) - 1 : 0)) + (align) - 1)/(align)))) + +void * +memalign(size_t align, size_t size) +{ cl_object x = alloc_simple_string(size); + x->string.self = (char *)ALLOC_ALIGNED(alloc, size, align); + malloc_list = make_cons(x, malloc_list); + return x->string.self; +} + +# ifdef WANT_VALLOC +char * +valloc(size_t size) +{ return memalign(getpagesize(), size);} +# endif WANT_VALLOC +#endif NEED_MALLOC diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d new file mode 100644 index 000000000..1f5c8ec32 --- /dev/null +++ b/src/c/alloc_2.d @@ -0,0 +1,291 @@ +/* + alloc_2.c -- Memory allocation based on the Boehmn GC. +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "page.h" + +/********************************************************** + * OBJECT ALLOCATION * + **********************************************************/ + +struct typemanager tm_table[(int)t_end]; + +#ifdef alloc_object +#undef alloc_object +#endif + +cl_object +alloc_object(enum type t) +{ + register cl_object obj; + register struct typemanager *tm; + + switch (t) { + case t_fixnum: + return MAKE_FIXNUM(0); /* Immediate fixnum */ + case t_character: + return code_char(' '); /* Immediate character */ + default: + } + if (t < t_start || t >= t_end) { + printf("\ttype = %d\n", t); + error("alloc botch."); + } + tm = tm_of(t); + + start_critical_section(); + obj = GC_malloc(tm->tm_size); + obj->d.t = t; + /* GC_malloc already resets objects */ + end_critical_section(); + + return obj; +} + +#ifdef make_cons +#undef make_cons +#endif + +cl_object +make_cons(cl_object a, cl_object d) +{ + cl_object obj; + + start_critical_section(); + + obj = GC_malloc(sizeof(struct cons)); + obj->d.t = (short)t_cons; + CAR(obj) = a; + CDR(obj) = d; + + end_critical_section(); + + return obj; +} + +cl_object +alloc_instance(cl_index slots) +{ + cl_object i; + i = alloc_object(t_instance); + i->instance.slots = alloc_align(sizeof(cl_object) * slots, sizeof(cl_object)); + i->instance.length = slots; + return i; +} + +void * +alloc(size_t n) +{ + void *output; + start_critical_section(); + output = GC_malloc(n); + end_critical_section(); + return output; +} + +void * +alloc_atomic(size_t n) +{ + void *output; + start_critical_section(); + output = GC_malloc_atomic(n); + end_critical_section(); + return output; +} + +/* + * adds a contblock to the list of available ones, pointed by cb_pointer, + * sorted by increasing size. + */ +void +dealloc(void *p, size_t s) +{ + GC_free(p); +} + +/* + * align must be a power of 2 representing the alignment boundary + * required for the block. + */ +void * +alloc_align(size_t size, size_t align) +{ + char *output; + start_critical_section(); + align--; + output = GC_malloc(size + align); + output = (char*)(((cl_fixnum)output + align) & ~align); + end_critical_section(); + return output; +} + +/* + * align must be a power of 2 representing the alignment boundary + * required for the block. + */ +void * +alloc_atomic_align(size_t size, size_t align) +{ + char *output; + start_critical_section(); + align--; + output = GC_malloc(size + align); + output = (char*)(((cl_fixnum)output + align) & ~align); + end_critical_section(); + return output; +} + +static void +init_tm(enum type t, char *name, size_t elsize) +{ + struct typemanager *tm = &tm_table[(int)t]; + tm->tm_name = name; + tm->tm_size = elsize; +} + +static int alloc_initialized = FALSE; + +void +init_alloc(void) +{ + if (alloc_initialized) return; + alloc_initialized = TRUE; + + init_tm(t_shortfloat, "SHORT-FLOAT", /* 8 */ + sizeof(struct shortfloat_struct)); + init_tm(t_cons, "CONS", sizeof(struct cons)); /* 12 */ + init_tm(t_longfloat, "LONG-FLOAT", /* 16 */ + sizeof(struct longfloat_struct)); + init_tm(t_bytecodes, "bBYTECODES", sizeof(struct bytecodes)); + init_tm(t_string, "STRING", sizeof(struct string)); /* 20 */ + init_tm(t_array, "ARRAY", sizeof(struct array)); /* 24 */ + init_tm(t_pathname, "PATHNAME", sizeof(struct pathname)); /* 28 */ + init_tm(t_symbol, "SYMBOL", sizeof(struct symbol)); /* 32 */ + init_tm(t_package, "PACKAGE", sizeof(struct package)); /* 36 */ + init_tm(t_codeblock, "CODEBLOCK", sizeof(struct codeblock), 1); + init_tm(t_bignum, "BIGNUM", sizeof(struct bignum)); + init_tm(t_ratio, "RATIO", sizeof(struct ratio)); + init_tm(t_complex, "COMPLEX", sizeof(struct complex)); + init_tm(t_hashtable, "HASH-TABLE", sizeof(struct hashtable)); + init_tm(t_vector, "VECTOR", sizeof(struct vector)); + init_tm(t_bitvector, "BIT-VECTOR", sizeof(struct vector)); + init_tm(t_stream, "STREAM", sizeof(struct stream)); + init_tm(t_random, "RANDOM-STATE", sizeof(struct random)); + init_tm(t_readtable, "READTABLE", sizeof(struct readtable)); + init_tm(t_cfun, "CFUN", sizeof(struct cfun)); + init_tm(t_cclosure, "CCLOSURE", sizeof(struct cclosure)); +#ifndef CLOS + init_tm(t_structure, "STRUCTURE", sizeof(struct structure)); +#else + init_tm(t_instance, "INSTANCE", sizeof(struct instance)); + init_tm(t_gfun, "GFUN", sizeof(struct gfun)); +#endif CLOS +#ifdef THREADS + init_tm(t_cont, "CONT", sizeof(struct cont)); + init_tm(t_thread, "THREAD", sizeof(struct thread)); +#endif THREADS +} + +/********************************************************** + * MALLOC SUBSTITUTION * + **********************************************************/ + +#ifdef NEED_MALLOC +#undef malloc +#undef calloc +#undef free +#undef cfree +#undef realloc + +/* FIXME! Shouldn't this be thread safe? */ +void * +malloc(size_t size) +{ + return GC_malloc(size); +} + +void +free(void *ptr) +{ + GC_free(ptr); +} + +void * +realloc(void *ptr, size_t size) +{ + return GC_realloc(ptr, size); +} + +void * +calloc(size_t nelem, size_t elsize) +{ + char *ptr; + size_t i; + ptr = GC_malloc(i = nelem*elsize); + memset(ptr, 0 , i); + return ptr; +} + +void +cfree(void *ptr) +{ + GC_free(ptr); +} + +#define ALLOC_ALIGNED(f, size, align) \ + ((align) <= 4 ? (int)(f)(size) : \ + ((align) * (((unsigned)(f)(size + (size ? (align) - 1 : 0)) + (align) - 1)/(align)))) + +void * +memalign(size_t align, size_t size) +{ + return (void *)ALLOC_ALIGNED(GC_malloc, size, align); +} + +# ifdef WANT_VALLOC +char * +valloc(size_t size) +{ + return memalign(getpagesize(), size); +} +# endif WANT_VALLOC +#endif NEED_MALLOC + + +/********************************************************** + * GARBAGE COLLECTION * + **********************************************************/ + +cl_object siVgc_verbose; +cl_object siVgc_message; + +void +register_root(cl_object *p) +{ + GC_add_roots(p, p+1); +} + +@(defun gc (area) +@ + gc(0); + @(return) +@) + +void +gc(enum type new_name) +{ + start_critical_section(); + GC_gcollect(); + end_critical_section(); +} diff --git a/src/c/apply.d b/src/c/apply.d new file mode 100644 index 000000000..433b85cd3 --- /dev/null +++ b/src/c/apply.d @@ -0,0 +1,675 @@ +/* + apply.c -- Interface to C call mechanism. +*/ +/* + Copyright (c) 1993, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +cl_object +APPLY(int n, cl_object (*fn)(), cl_object *x) +#ifdef ARGCALL +{ int i; ARGSTACK(n); + for (i = 0; i < n; i++) + CPUSH(*x++); + return ARGCALL(n, fn); +} +#else +{ + switch (n) { + case 0: return (*fn)(n); + case 1: return (*fn)(n, x[0]); + case 2: return (*fn)(n, x[0],x[1]); + case 3: return (*fn)(n, x[0],x[1],x[2]); + case 4: return (*fn)(n, x[0],x[1],x[2],x[3]); + case 5: return (*fn)(n, x[0],x[1],x[2],x[3],x[4]); + case 6: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5]); + case 7: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6]); + case 8: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]); + case 9: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8]); + case 10: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9]); + case 11: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10]); + case 12: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11]); + case 13: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12]); + case 14: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13]); + case 15: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14]); + case 16: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15]); + case 17: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16]); + case 18: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17]); + case 19: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18]); + case 20: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19]); + case 21: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20]); + case 22: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21]); + case 23: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22]); + case 24: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23]); + case 25: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24]); + case 26: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25]); + case 27: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26]); + case 28: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27]); + case 29: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28]); + case 30: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29]); + case 31: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30]); + case 32: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31]); + case 33: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32]); + case 34: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33]); + case 35: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34]); + case 36: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35]); + case 37: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36]); + case 38: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37]); + case 39: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38]); + case 40: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39]); + case 41: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40]); + case 42: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41]); + case 43: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42]); + case 44: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43]); + case 45: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44]); + case 46: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45]); + case 47: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46]); + case 48: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47]); + case 49: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48]); + case 50: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49]); + case 51: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50]); + case 52: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51]); + case 53: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52]); + case 54: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53]); + case 55: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54]); + case 56: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55]); + case 57: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56]); + case 58: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57]); + case 59: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58]); + case 60: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59]); + case 61: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60]); + case 62: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60],x[61]); + case 63: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60],x[61],x[62]); + case 64: return (*fn)(n, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60],x[61],x[62],x[63]); + default: FEprogram_error("Exceeded call-arguments-limit.", 0); + } +} +#endif ARGCALL + +cl_object +APPLY_closure(int n, cl_object (*fn)(), cl_object cl, cl_object *x) +#ifdef ARGCALL +{ int i; ARGSTACK(n+1); + CPUSH(cl); + for (i = 0; i < n; i++) + CPUSH(*x++); + return ARGCALL(n++, fn); +} +#else +{ + switch (++n) { + case 1: return (*fn)(n, cl); + case 2: return (*fn)(n, cl, x[0]); + case 3: return (*fn)(n, cl, x[0],x[1]); + case 4: return (*fn)(n, cl, x[0],x[1],x[2]); + case 5: return (*fn)(n, cl, x[0],x[1],x[2],x[3]); + case 6: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4]); + case 7: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5]); + case 8: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6]); + case 9: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]); + case 10: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8]); + case 11: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9]); + case 12: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10]); + case 13: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11]); + case 14: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12]); + case 15: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13]); + case 16: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14]); + case 17: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15]); + case 18: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16]); + case 19: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17]); + case 20: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18]); + case 21: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19]); + case 22: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20]); + case 23: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21]); + case 24: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22]); + case 25: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23]); + case 26: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24]); + case 27: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25]); + case 28: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26]); + case 29: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27]); + case 30: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28]); + case 31: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29]); + case 32: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30]); + case 33: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31]); + case 34: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32]); + case 35: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33]); + case 36: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34]); + case 37: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35]); + case 38: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36]); + case 39: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37]); + case 40: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38]); + case 41: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39]); + case 42: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40]); + case 43: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41]); + case 44: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42]); + case 45: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43]); + case 46: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44]); + case 47: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45]); + case 48: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46]); + case 49: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47]); + case 50: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48]); + case 51: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49]); + case 52: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50]); + case 53: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51]); + case 54: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52]); + case 55: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53]); + case 56: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54]); + case 57: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55]); + case 58: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56]); + case 59: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57]); + case 60: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58]); + case 61: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59]); + case 62: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60]); + case 63: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60],x[61]); + case 64: return (*fn)(n, cl, x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], + x[8],x[9],x[10],x[11],x[12],x[13],x[14], + x[15],x[16],x[17],x[18],x[19],x[20],x[21], + x[22],x[23],x[24],x[25],x[26],x[27],x[28], + x[29],x[30],x[31],x[32],x[33],x[34],x[35], + x[36],x[37],x[38],x[39],x[40],x[41],x[42], + x[43],x[44],x[45],x[46],x[47],x[48],x[49], + x[50],x[51],x[52],x[53],x[54],x[55],x[56], + x[57],x[58],x[59],x[60],x[61],x[62]); + default: FEprogram_error("Exceeded call-arguments-limit.", 0); + } +} +#endif ARGCALL diff --git a/src/c/array.d b/src/c/array.d new file mode 100644 index 000000000..ee2f6b5d0 --- /dev/null +++ b/src/c/array.d @@ -0,0 +1,724 @@ +/* + array.c -- Array routines +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +static void displace (cl_object from, cl_object to, cl_object offset); +static void check_displaced (cl_object dlist, cl_object orig, cl_index newdim); +extern enum aelttype get_aelttype (cl_object x); + +cl_index +object_to_index(cl_object n) +{ + switch (type_of(n)) { + case t_fixnum: { + cl_fixnum out = fix(n); + if (out < 0 || out >= ADIMLIM) + FEtype_error_index(n); + return out; + } + case t_bignum: + FEtype_error_index(n); + default: + FEtype_error_integer(n); + } +} + +@(defun aref (x &rest indx) + cl_index r, s, i, j; + cl_object index; +@ + r = narg - 1; + switch (type_of(x)) { + case t_array: + if (r != x->array.rank) + FEerror("Wrong number of indices.", 0); + for (i = j = 0; i < r; i++) { + index = va_arg(indx, cl_object); + if ((s = fixnnint(index)) >= x->array.dims[i]) + FEerror("The ~:R index, ~S, to the array~%\ +~S is too large.", 3, MAKE_FIXNUM(i+1), index, x); + j = j*(x->array.dims[i]) + s; + } + break; + + case t_vector: + case t_string: + case t_bitvector: + if (r != 1) + FEerror("Wrong number of indices.", 0); + index = va_arg(indx, cl_object); + j = fixnnint(index); + if (j >= x->vector.dim) + FEerror("The first index, ~S, to the array ~S is too large.", + 2, index, x); + break; + + default: + FEwrong_type_argument(Sarray, x); + } + @(return aref(x, j)) +@) + +cl_object +aref(cl_object x, cl_index index) +{ + if (index >= x->array.dim) + FEerror("The index, ~D, is too large.", 1, MAKE_FIXNUM(index)); + switch ((enum aelttype)array_elttype(x)) { + case aet_object: + return(x->array.self.t[index]); + + case aet_ch: + return(code_char(x->string.self[index])); + + case aet_bit: + index += x->vector.offset; + if (x->vector.self.bit[index/CHAR_BIT] & (0200>>index%CHAR_BIT)) + return(MAKE_FIXNUM(1)); + else + return(MAKE_FIXNUM(0)); + case aet_fix: + return(MAKE_FIXNUM(x->array.self.fix[index])); + + case aet_sf: + return(make_shortfloat(x->array.self.sf[index])); + + case aet_lf: + return(make_longfloat(x->array.self.lf[index])); + + default: + internal_error("aref"); + } +} + +cl_object +aref1(cl_object v, cl_index index) +{ + switch (type_of(v)) { + case t_vector: + case t_bitvector: + return(aref(v, index)); + + case t_string: + if (index >= v->string.dim) + FEerror("The index, ~D, is too large.", 1, MAKE_FIXNUM(index)); + return(code_char(v->string.self[index])); + + default: + FEerror("~S is not a vector.", 1, v); + } +} + +/* + Internal function for setting array elements: + + (si:aset value array dim0 ... dimN) +*/ +@(defun si::aset (v x &rest dims) + cl_index r, s, i, j; + cl_object index; +@ + r = narg - 2; + switch (type_of(x)) { + case t_array: + if (r != x->array.rank) + FEerror("Wrong number of indices.", 0); + for (i = j = 0; i < r; i++) { + index = va_arg(dims, cl_object); + if ((s = fixnnint(index)) >= x->array.dims[i]) + FEerror("The ~:R index, ~S, to the array ~S is too large.", + 3, MAKE_FIXNUM(i+1), index, x); + j = j*(x->array.dims[i]) + s; + } + break; + + case t_vector: + case t_string: + case t_bitvector: + if (r != 1) + FEerror("Wrong number of indices.", 0); + index = va_arg(dims, cl_object); + j = fixnnint(index); + if (j >= x->vector.dim) + FEerror("The first index, ~S, to the array ~S is too large.", + 2, index, x); + break; + + default: + FEwrong_type_argument(Sarray, x); + } + @(return aset(x, j, v)) +@) + +cl_object +aset(cl_object x, cl_index index, cl_object value) +{ + if (index >= x->array.dim) + FEerror("The index, ~D, too large.", 1, MAKE_FIXNUM(index)); + switch (array_elttype(x)) { + case aet_object: + x->array.self.t[index] = value; + break; + + case aet_ch: + /* INV: char_code() checks the type of `value' */ + x->string.self[index] = char_code(value); + break; + + case aet_bit: { + cl_fixnum i = fixint(value); + if (i != 0 && i != 1) + FEerror("~S is not a bit.", 1, value); + index += x->vector.offset; + if (i == 0) + x->vector.self.bit[index/CHAR_BIT] &= ~(0200>>index%CHAR_BIT); + else + x->vector.self.bit[index/CHAR_BIT] |= 0200>>index%CHAR_BIT; + break; + } + case aet_fix: + x->array.self.fix[index] = fixint(value); + break; + + case aet_sf: + x->array.self.sf[index] = object_to_float(value); + break; + + case aet_lf: + x->array.self.lf[index] = object_to_double(value); + break; + } + return(value); +} + +cl_object +aset1(cl_object v, cl_index index, cl_object val) +{ + switch (type_of(v)) { + case t_vector: + case t_bitvector: + return(aset(v, index, val)); + + case t_string: + if (index >= v->string.dim) + FEerror("The index, ~D, is too large", 1, MAKE_FIXNUM(index)); + /* INV: char_code() checks the type of `val' */ + v->string.self[index] = char_code(val); + return(val); + + default: + FEerror("~S is not a vector.", 1, v); + } + +} + +/* + Internal function for making arrays of more than one dimension: + + (si:make-pure-array element-type adjustable + displaced-to displaced-index-offset + dim0 dim1 ... ) +*/ +@(defun si::make_pure_array (etype adj displ disploff &rest dims) + cl_index r, s, i, j; + cl_object x; +@ + r = narg - 4; + x = alloc_object(t_array); + x->array.displaced = Cnil; + x->array.self.t = NULL; /* for GC sake */ + x->array.rank = r; + x->array.elttype = (short)get_aelttype(etype); + x->array.dims = alloc_atomic_align(sizeof(int)*r, sizeof(int)); + if (r >= ARANKLIM) + FEerror("The array rank, ~R, is too large.", 1, MAKE_FIXNUM(r)); + for (i = 0, s = 1; i < r; i++) { + cl_object index = va_arg(dims, cl_object); + if ((j = fixnnint(index)) > ADIMLIM) + FEerror("The ~:R array dimension, ~D, is too large.", + 2, MAKE_FIXNUM(i+1), index); + s *= (x->array.dims[i] = j); + if (s > ATOTLIM) + FEerror("The array total size, ~D, is too large.", 1, MAKE_FIXNUM(s)); + } + x->array.dim = s; + x->array.adjustable = adj != Cnil; + if (Null(displ)) + array_allocself(x); + else + displace(x, displ, disploff); + @(return x) +@) + +/* + Internal function for making vectors: + + (si:make-vector element-type dimension adjustable fill-pointer + displaced-to displaced-index-offset) +*/ +@(defun si::make_vector (etype dim adj fillp displ disploff) + cl_index d, f; + cl_object x; + enum aelttype aet; +@ + aet = get_aelttype(etype); + if ((d = fixnnint(dim)) > ADIMLIM) + FEerror("The vector dimension, ~D, is too large.", 1, dim); + f = d; + if (aet == aet_ch) { + x = alloc_object(t_string); + d++; /* extra for null terminator */ + } + else if (aet == aet_bit) + x = alloc_object(t_bitvector); + else { + x = alloc_object(t_vector); + x->vector.elttype = (short)aet; + } + x->vector.self.t = NULL; /* for GC sake */ + x->vector.displaced = Cnil; + x->vector.dim = d; + x->vector.adjustable = adj != Cnil; + + if (Null(fillp)) + x->vector.hasfillp = FALSE; + else if (fillp == Ct) + x->vector.hasfillp = TRUE; + else if ((f = fixnnint(fillp)) > d) + FEerror("The fill-pointer ~S is too large.", 1, fillp); + else + x->vector.hasfillp = TRUE; + x->vector.fillp = f; + + if (Null(displ)) + array_allocself(x); + else + displace(x, displ, disploff); + @(return x) +@) + +void +array_allocself(cl_object x) +{ + cl_index i, d; + + d = x->array.dim; +#ifdef THREADS + start_critical_section(); /* avoid losing elts */ +#endif THREADS + switch (array_elttype(x)) { + + /* assign self field only after it has been filled, for GC sake */ + case aet_object: { + cl_object *elts; + elts = alloc_align(sizeof(cl_object)*d, sizeof(cl_object)); + for (i = 0; i < d; i++) + elts[i] = Cnil; + x->array.self.t = elts; + break; + } + case aet_ch: { + char *elts; + elts = alloc_atomic(d); + for (i = 0; i < d; i++) + elts[i] = ' '; + if (type_of(x) == t_string) elts[d-1] = '\0'; + x->string.self = elts; + break; + } + case aet_bit: { + char *elts; + d = (d+(CHAR_BIT-1))/CHAR_BIT; + elts = alloc_atomic(d); + for (i = 0; i < d; i++) + elts[i] = '\0'; + x->vector.offset = 0; + x->vector.self.bit = elts; + break; + } + case aet_fix: { + cl_fixnum *elts; + elts = alloc_atomic_align(sizeof(cl_fixnum)*d, sizeof(cl_fixnum)); + for (i = 0; i < d; i++) + elts[i] = 0; + x->array.self.fix = elts; + break; + } + case aet_sf: { + float *elts; + elts = alloc_atomic_align(sizeof(float)*d, sizeof(float)); + for (i = 0; i < d; i++) + elts[i] = 0.0; + x->array.self.sf = elts; + break; + } + case aet_lf: { + double *elts; + elts = alloc_atomic_align(sizeof(double)*d, sizeof(double)); + for (i = 0; i < d; i++) + elts[i] = 0.0; + x->array.self.lf = elts; + break; + } + } +#ifdef THREADS + end_critical_section(); +#endif THREADS +} + +enum aelttype +get_aelttype(cl_object x) +{ + if (x == Sbase_char) + return(aet_ch); + else if (x == Sbit) + return(aet_bit); + else if (x == Sfixnum) + return(aet_fix); + else if (x == Ssingle_float || x == Sshort_float) + return(aet_sf); + else if (x == Slong_float || x == Sdouble_float) + return(aet_lf); +/* else if (x == Ssigned_char) + return(aet_char); + else if (x == Sunsigned_char) + return(aet_uchar); + else if (x == Ssigned_short) + return(aet_short); + else if (x == Sunsigned_short) + return(aet_ushort); +*/ else + return(aet_object); +} + +void * +array_address(cl_object x, cl_index inc) +{ + switch(array_elttype(x)) { + case aet_object: + return x->array.self.t + inc; + case aet_fix: + return x->array.self.fix + inc; + case aet_sf: + return x->array.self.t + inc; + case aet_ch: + return x->string.self + inc; + case aet_lf: + return x->array.self.lf + inc; + + default: + FEerror("Bad array type", 0); + } +} + +@(defun array_element_type (a) + cl_object output; +@ + switch (array_elttype(a)) { + case aet_object: output = Ct; break; + case aet_ch: output = Sbase_char; break; + case aet_bit: output = Sbit; break; + case aet_fix: output = Sfixnum; break; + case aet_sf: output = Sshort_float; break; + case aet_lf: output = Slong_float; break; + } + @(return output) +@) + +/* + Displace(from, to, offset) displaces the from-array + to the to-array (the original array) by the specified offset. + It changes the a_displaced field of both arrays. + The field is a cons; the car of the from-array points to + the to-array and the cdr of the to-array is a list of arrays + displaced to the to-array, so the from-array is pushed to the + cdr of the to-array's a_displaced. +*/ +static void +displace(cl_object from, cl_object to, cl_object offset) +{ + cl_index j; + enum aelttype totype, fromtype; + + j = fixnnint(offset); + totype = array_elttype(to); + fromtype = array_elttype(from); + if (totype != fromtype) + FEerror("Cannot displace the array,~%\ +because the element types don't match.", 0); + if (j + from->array.dim > to->array.dim) + FEerror("Cannot displace the array,~%\ +because the total size of the to-array is too small.", 0); + from->array.displaced = CONS(to, Cnil); + if (Null(to->array.displaced)) + to->array.displaced = CONS(Cnil, Cnil); + CDR(to->array.displaced) = + CONS(from, CDR(to->array.displaced)); + if (fromtype == aet_bit) { + j += to->vector.offset; + from->vector.self.bit = to->vector.self.bit + j/CHAR_BIT; + from->vector.offset = j%CHAR_BIT; + } +#ifndef BYTE_ADDRESS + else if (fromtype != aet_ch) + from->array.self.t = (cl_object *)(array_address(to, j)); +#endif + else + from->string.self = array_address(to, j); +} + +/* + Check_displaced(dlist, orig, newdim) checks if the displaced + arrays can keep the displacement when the original array is + adjusted. + Dlist is the list of displaced arrays, orig is the original array + and newdim is the new dimension of the original array. +*/ +static void +check_displaced(cl_object dlist, cl_object orig, cl_index newdim) +{ + cl_object x; + + for (; dlist != Cnil; dlist = CDR(dlist)) { + x = CAR(dlist); + if (x->array.self.t == NULL) + continue; + if (array_elttype(x) != aet_bit) { + if (array_address(x, x->array.dim) > + array_address(orig, newdim)) + FEerror("Can't keep displacement.", 0); + } else { + if ((x->vector.self.bit - orig->vector.self.bit)*CHAR_BIT + + x->vector.dim - newdim + + x->vector.offset - orig->vector.offset > 0) + FEerror("Can't keep displacement.", 0); + } + check_displaced(CDR(x->array.displaced), orig, newdim); + } +} + +/* + Adjust_displaced(x, diff) adds the int value diff + to the a_self field of the array x and all the arrays displaced to x. + This function is used in siLreplace_array (ADJUST-ARRAY) and + the garbage collector. +*/ +void adjust_displaced(cl_object x, ptrdiff_t diff) +{ + if (x->array.self.t != NULL) + x->array.self.t = (cl_object *)((char*)(x->array.self.t) + diff); + for (x = CDR(x->array.displaced); x != Cnil; x = CDR(x)) + adjust_displaced(CAR(x), diff); +} + +enum aelttype +array_elttype(cl_object x) +{ + switch(type_of(x)) { + case t_array: + case t_vector: + return((enum aelttype)x->array.elttype); + + case t_string: + return(aet_ch); + + case t_bitvector: + return(aet_bit); + + default: + FEwrong_type_argument(Sarray, x); + } +} + +@(defun array_rank (a) +@ + assert_type_array(a); + @(return ((type_of(a) == t_array) ? MAKE_FIXNUM(a->array.rank) + : MAKE_FIXNUM(1))) +@) + +@(defun array_dimension (a index) + cl_index i, dim; +@ + i = fixnnint(index); + switch (type_of(a)) { + case t_array: + if (i >= a->array.rank) + goto ILLEGAL; + dim = a->array.dims[i]; + break; + case t_string: + if (i != 0) + goto ILLEGAL; + dim = a->string.fillp; + break; + case t_vector: + case t_bitvector: + if (i != 0) +ILLEGAL: FEerror("~S is an illegal axis-number to the array ~S.", + 2, index, a); + dim = a->vector.dim; + break; + default: + FEwrong_type_argument(Sarray, a); + } + @(return MAKE_FIXNUM(dim)) +@) + +@(defun array_total_size (a) +@ + assert_type_array(a); + @(return MAKE_FIXNUM(a->array.dim)) +@) + +@(defun adjustable_array_p (a) +@ + assert_type_array(a); + @(return (a->array.adjustable ? Ct : Cnil)) +@) + +/* + Internal function for checking if an array is displaced. +*/ +@(defun si::displaced_array_p (a) +@ + assert_type_array(a); + @(return ((CAR(a->array.displaced) != Cnil) ? Ct : Cnil)) +@) + +@(defun svref (x index) + cl_index i; +@ + if (type_of(x) != t_vector || + x->vector.adjustable || + x->vector.hasfillp || + CAR(x->vector.displaced) != Cnil || + (enum aelttype)x->vector.elttype != aet_object) + FEwrong_type_argument(Ssimple_vector, x); + if ((i = fixnnint(index)) >= x->vector.dim) + illegal_index(x, index); + @(return x->vector.self.t[i]) +@) + +@(defun si::svset (x index v) + cl_index i; +@ + if (type_of(x) != t_vector || + x->vector.adjustable || + x->vector.hasfillp || + CAR(x->vector.displaced) != Cnil || + (enum aelttype)x->vector.elttype != aet_object) + FEwrong_type_argument(Ssimple_vector, x); + if ((i = fixnnint(index)) >= x->vector.dim) + illegal_index(x, index); + @(return (x->vector.self.t[i] = v)) +@) + +@(defun array_has_fill_pointer_p (a) + cl_object r; +@ + switch (type_of(a)) { + case t_array: + r = Cnil; break; + case t_vector: + case t_bitvector: + case t_string: + r = a->vector.hasfillp? Ct : Cnil; + break; + default: + FEwrong_type_argument(Sarray, a); + } + @(return r) +@) + +@(defun fill_pointer (a) +@ + assert_type_vector(a); + if (a->vector.hasfillp) + @(return MAKE_FIXNUM(a->vector.fillp)) + FEerror("The vector ~S has no fill pointer.", 1, a); +@) + +/* + Internal function for setting fill pointer. +*/ +@(defun si::fill_pointer_set (a fp) + cl_index i; +@ + assert_type_vector(a); + i = fixnnint(fp); + if (a->vector.hasfillp) + if (i > a->vector.dim) + FEerror("The fill-pointer ~S is too large", 1, fp); + else + a->vector.fillp = i; + else + FEerror("The vector ~S has no fill pointer.", 1, a); + @(return fp) +@) + +/* + Internal function for replacing the contents of arrays: + + (si:replace-array old-array new-array). + + Used in ADJUST-ARRAY. +*/ +@(defun si::replace_array (old new) + cl_object displaced, dlist; + ptrdiff_t diff; +@ + if (type_of(old) != type_of(new) + || (type_of(old) == t_array && old->array.rank != new->array.rank)) + goto CANNOT; + if (!old->array.adjustable) + FEerror("~S is not adjustable.", 1, old); + diff = (char*)(new->array.self.t) - (char*)(old->array.self.t); + dlist = CDR(old->array.displaced); + displaced = CONS(CAR(new->array.displaced), dlist); + check_displaced(dlist, old, new->array.dim); + adjust_displaced(old, diff); +/* undisplace(old); */ + switch (type_of(old)) { + case t_array: + case t_vector: + case t_bitvector: + old->array = new->array; + break; + + case t_string: + old->string = new->string; + break; + + default: + goto CANNOT; + } + old->array.displaced = displaced; + @(return old) + + CANNOT: + FEerror("Cannot replace the array ~S by the array ~S.", 2, old, new); +@) + +void +init_array(void) +{ + make_constant("ARRAY-RANK-LIMIT", MAKE_FIXNUM(ARANKLIM)); + make_constant("ARRAY-DIMENSION-LIMIT", MAKE_FIXNUM(ADIMLIM)); + make_constant("ARRAY-TOTAL-SIZE-LIMIT", MAKE_FIXNUM(ATOTLIM)); +} diff --git a/src/c/assignment.d b/src/c/assignment.d new file mode 100644 index 000000000..48db12d10 --- /dev/null +++ b/src/c/assignment.d @@ -0,0 +1,179 @@ +/* + assignment.c -- Assignment. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include + +cl_object Ssetf, Spsetf, siSsetf_symbol; +cl_object siSclear_compiler_properties; + +#ifdef PDE +cl_object siVrecord_source_pathname_p, siSrecord_source_pathname; +extern cl_object Sdefun; +#endif PDE + +cl_object +set(cl_object var, cl_object val) +{ + if (!SYMBOLP(var)) + FEtype_error_symbol(var); + if (var->symbol.stype == stp_constant) + FEinvalid_variable("Cannot assign to the constant ~S.", var); + return (SYM_VAL(var) = val); +} + +@(defun set (var val) +@ + @(return set(var, val)) +@) + +cl_object +setf_namep(cl_object fun_spec) +{ cl_object cdr; + if (CONSP(fun_spec) && !endp(cdr = CDR(fun_spec)) && + endp(CDR(cdr)) && CAR(fun_spec) == Ssetf) { + cl_object fn_name, sym; + fn_name = CAR(cdr); + sym = getf(fn_name->symbol.plist, siSsetf_symbol, Cnil); + if (Null(sym) || !SYMBOLP(sym)) { + cl_object fn_str = fn_name->symbol.name; + int l = fn_str->string.fillp + 7; + cl_object string = alloc_simple_string(l); + char *str = alloc_atomic(l+1); + string->string.self = str; + strncpy(str, "(SETF ", 6); + strncpy(str + 6, fn_str->string.self, fn_str->string.fillp); + str[l-1] = ')'; + str[l] = '\0'; + sym = intern(string, fn_name->symbol.hpack); + fn_name->symbol.plist = + putf(fn_name->symbol.plist, sym, siSsetf_symbol); + } + return(sym); + } else return(OBJNULL); +} + +@(defun si::setf_namep (arg) + cl_object x; +@ + x = setf_namep(arg); + @(return ((x != OBJNULL) ? x : Cnil)) +@) + +@(defun si::fset (fun def &optional macro pprint) + enum type t; +@ + if (!SYMBOLP(fun)) { + cl_object sym; + if ((sym=setf_namep(fun)) != OBJNULL) + fun = sym; + else + FEtype_error_symbol(fun); + } + if (fun->symbol.isform) { + if (fun->symbol.mflag) { + if (symbol_value(siVinhibit_macro_special) != Cnil) + fun->symbol.isform = FALSE; + } else if (symbol_value(siVinhibit_macro_special) != Cnil) + FEerror("~S, a special form, cannot be redefined.", 1, fun); + } + clear_compiler_properties(fun); + if (fun->symbol.hpack->pack.locked && SYM_FUN(fun) != OBJNULL) + funcall(3, Swarn, make_simple_string("~S is being redefined."), fun); + t = type_of(def); + if (t == t_bytecodes || t == t_cfun || t == t_cclosure) { + SYM_FUN(fun) = def; +#ifdef CLOS + } else if (t == t_gfun) { + SYM_FUN(fun) = def; +#endif + } else { + FEinvalid_function(def); + } + fun->symbol.mflag = !Null(macro); + if (pprint != Cnil) + fun->symbol.plist + = putf(fun->symbol.plist, pprint, siSpretty_print_format); + @(return fun) +@) + +@(defun makunbound (sym) +@ + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + if ((enum stype)sym->symbol.stype == stp_constant) + FEinvalid_variable("Cannot unbind the constant ~S.", sym); + SYM_VAL(sym) = OBJNULL; + @(return sym) +@) + +@(defun fmakunbound (sym) +@ + if (!SYMBOLP(sym)) { + cl_object sym1; + if ((sym1=setf_namep(sym)) != OBJNULL) + sym = sym1; + else + FEtype_error_symbol(sym); + } + if (sym->symbol.isform) { + if (sym->symbol.mflag) { + if (symbol_value(siVinhibit_macro_special) != Cnil) + sym->symbol.isform = FALSE; + } else if (symbol_value(siVinhibit_macro_special) != Cnil) + FEerror("~S, a special form, cannot be redefined.", 1, sym); + } + clear_compiler_properties(sym); +#ifdef PDE + remprop(sym, Sdefun); +#endif PDE + if (sym->symbol.hpack->pack.locked && SYM_FUN(sym) != OBJNULL) + funcall(3, Swarn, make_simple_string("~S is being redefined."), sym); + SYM_FUN(sym) = OBJNULL; + sym->symbol.mflag = FALSE; + @(return sym) +@) + +void +clear_compiler_properties(cl_object sym) +{ + siLunlink_symbol(1, sym); + if (symbol_value(siVinhibit_macro_special) != Cnil) + (void)funcall(2, siSclear_compiler_properties, sym); +} + +@(defun si::clear_compiler_properties (sym) +@ + @(return sym) +@) + +#ifdef PDE +void +record_source_pathname(cl_object sym, cl_object def) +{ + if (symbol_value(siVrecord_source_pathname_p) != Cnil) + (void)funcall(3, siSrecord_source_pathname, sym, def); +} +#endif PDE + +void +init_assignment(void) +{ +#ifdef PDE + SYM_VAL(siVrecord_source_pathname_p) = Cnil; +#endif PDE +} diff --git a/src/c/backq.d b/src/c/backq.d new file mode 100644 index 000000000..ff7836c04 --- /dev/null +++ b/src/c/backq.d @@ -0,0 +1,306 @@ +/* + backq.c -- Backquote mechanism. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ +#ifndef THREADS +int backq_level; +#endif +/******************************* ------- ******************************/ + +#define read_char(in) (*read_ch_fun)(in) + +/* #define attach(x) (*px = CONS(x, *px)) */ +#define attach(s) CDR(x) = CONS(s, CDR(x)); + +#define QUOTE 1 +#define EVAL 2 +#define LIST 3 +#define LISTA 4 +#define APPEND 5 +#define NCONC 6 + +cl_object siScomma; +cl_object siScomma_at; +cl_object siScomma_dot; + +cl_object SlistX; +cl_object Sappend; +cl_object Snconc; + +static cl_object +kwote(cl_object x) +{ + enum cl_type t = type_of(x); + if ((t == t_symbol && + ((enum stype)x->symbol.stype != stp_constant || SYM_VAL(x) != x)) + || t == t_cons || t == t_vector) + return(CONS(Squote, CONS(x, Cnil))); + else return(x); +} + +/* + Backq_cdr(&x) puts result into x and returns one of + + QUOTE the form should be quoted + EVAL the form should be evaluated + LIST the form should be applied to LIST + LISTA the form should be applied to LIST* + APPEND the form should be applied to APPEND + NCONC the form should be applied to NCONC +*/ +int +backq_cdr(cl_object *px) +{ + cl_object x = *px; + int a, d; + + cs_check(px); + + if (ATOM(x)) + return(QUOTE); + if (CAR(x) == siScomma) { + *px = CDR(x); + return(EVAL); + } + if (CAR(x) == siScomma_at || CAR(x) == siScomma_dot) + FEerror(",@@ or ,. has appeared in an illegal position.", 0); + { cl_object ax, dx; + a = backq_car(&CAR(x)); + d = backq_cdr(&CDR(x)); + ax = CAR(x); dx = CDR(x); + if (d == QUOTE) + switch (a) { + case QUOTE: + return(QUOTE); + + case EVAL: + if (Null(dx)) + return(LIST); + if (CONSP(dx) && Null(CDR(dx))) { + CDR(x) = CONS(kwote(CAR(dx)), Cnil); + return(LIST); + } + CDR(x) = CONS(kwote(dx), Cnil); + return(LISTA); + + case APPEND: + case NCONC: + if (Null(dx)) { + *px = ax; + return(EVAL); + } + CDR(x) = CONS(kwote(dx), Cnil); + return(a); + + default: + error("backquote botch"); + } + if (d == EVAL) + switch (a) { + case QUOTE: + CAR(x) = kwote(ax); + CDR(x) = CONS(dx, Cnil); + return(LISTA); + + case EVAL: + CDR(x) = CONS(dx, Cnil); + return(LISTA); + + case APPEND: + case NCONC: + CDR(x) = CONS(dx, Cnil); + return(a); + + default: + error("backquote botch"); + } + if (d == a) + return(d); + switch (d) { + case LIST: + if (a == QUOTE) { + CAR(x) = kwote(ax); + return(LIST); + } + if (a == EVAL) + return(LIST); + attach(Slist); + break; + + case LISTA: + if (a == QUOTE) { + CAR(x) = kwote(ax); + return(LISTA); + } + if (a == EVAL) + return(LISTA); + attach(SlistX); + break; + + case APPEND: + attach(Sappend); + break; + + case NCONC: + attach(Snconc); + break; + + default: + error("backquote botch"); + } + switch (a) { + case QUOTE: + CAR(x) = kwote(ax); + CDR(x) = CONS(CDR(x), Cnil); + return(LISTA); + + case EVAL: + CDR(x) = CONS(CDR(x), Cnil); + return(LISTA); + + case APPEND: + case NCONC: + CDR(x) = CONS(CDR(x), Cnil); + return(a); + + default: + error("backquote botch"); + } + } +} + +/* + Backq_car(&x) puts result into x and returns one of + + QUOTE the form should be quoted + EVAL the form should be evaluated + APPEND the form should be appended + into the outer form + NCONC the form should be nconc'ed + into the outer form +*/ +int +backq_car(cl_object *px) +{ + cl_object x = *px; + int d; + + cs_check(px); + + if (ATOM(x)) + return(QUOTE); + if (CAR(x) == siScomma) { + *px = CDR(x); + return(EVAL); + } + if (CAR(x) == siScomma_at) { + *px = CDR(x); + return(APPEND); + } + if (CAR(x) == siScomma_dot) { + *px = CDR(x); + return(NCONC); + } + d = backq_cdr(px); + switch (d) { + case QUOTE: + case EVAL: + return(d); + + case LIST: +/* attach(Slist); */ + *px = CONS(Slist, *px); + break; + + case LISTA: +/* attach(SlistX); */ + *px = CONS(SlistX, *px); + break; + + case APPEND: +/* attach(Sappend); */ + *px = CONS(Sappend, *px); + break; + + case NCONC: +/* attach(Snconc); */ + *px = CONS(Snconc, *px); + break; + + default: + error("backquote botch"); + } + return(EVAL); +} + +cl_object +backq(cl_object x) +{ + int a; + + a = backq_car(&x); + if (a == APPEND || a == NCONC) + FEerror(",@@ or ,. has appeared in an illegal position.", 0); + if (a == QUOTE) + return(kwote(x)); + return(x); +} + +@(defun comma_reader (in c) + cl_object x, y; +@ + if (backq_level <= 0) + FEerror("A comma has appeared out of a backquote.", 0); + c = peek_char(FALSE, in); + if (c == code_char('@@')) { + x = siScomma_at; + read_char(in); + } else if (c == code_char('.')) { + x = siScomma_dot; + read_char(in); + } else + x = siScomma; + --backq_level; + y = read_object(in); + backq_level++; + @(return CONS(x, y)) +@) + +@(defun backquote_reader (in c) +@ + backq_level++; + in = read_object(in); + --backq_level; + @(return backq(in)) +@) + +#define make_cf(f) make_cfun((f), Cnil, NULL); + +void +init_backq(void) +{ + cl_object r; + + r = standard_readtable; + r->readtable.table['`'].syntax_type = cat_terminating; + r->readtable.table['`'].macro = make_cf(Lbackquote_reader); + r->readtable.table[','].syntax_type = cat_terminating; + r->readtable.table[','].macro = make_cf(Lcomma_reader); + + backq_level = 0; +} diff --git a/src/c/big.d b/src/c/big.d new file mode 100644 index 000000000..ebf37a559 --- /dev/null +++ b/src/c/big.d @@ -0,0 +1,269 @@ +/* + big.c -- Bignum routines. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +#ifndef THREADS +cl_object bignum_register[3]; +mp_limb_t bignum_register_limbs[3][BIGNUM_REGISTER_SIZE]; +#endif THREADS + +/* + * Using GMP multiple precision integers: + * + * typedef struct + * { + * long int alloc; // Number of limbs allocated and pointed + * // to by the D field. + * long int size; // abs(SIZE) is the number of limbs + * // the last field points to. If SIZE + * // is negative this is a negative number. + * unsigned long int *d; // Pointer to the limbs, + * // d[0] is the least significative. + * } MP_INT; + * + * typedef unsigned long int mp_limb_t; + * + */ + +void +big_register_free(cl_object x) +{ + /* FIXME! Is this thread safe? */ + if (x == bignum_register[0]) + x->big.big_limbs = bignum_register_limbs[0]; + else if (x == bignum_register[1]) + x->big.big_limbs = bignum_register_limbs[1]; + else if (x == bignum_register[2]) + x->big.big_limbs = bignum_register_limbs[2]; + else + error("big_register_free: unknown register"); + x->big.big_size = 0; + x->big.big_dim = BIGNUM_REGISTER_SIZE; +} + +cl_object +big_register_copy(cl_object old) +{ + cl_object new = alloc_object(t_bignum); + if (old->big.big_dim > BIGNUM_REGISTER_SIZE) { + /* The object already has suffered a mpz_realloc() so + we can use the pointer */ + new->big = old->big; + big_register_free(old); + } else { + /* As the bignum points to the bignum_register_limbs[] area + we must duplicate its contents. */ + mpz_init_set(new->big.big_num,old->big.big_num); + } + return new; +} + +cl_object +big_register_normalize(cl_object x) +{ + int s = x->big.big_size; + mp_limb_t y; + if (s == 0) + return(MAKE_FIXNUM(0)); + y = x->big.big_limbs[0]; + if (s == 1 && y <= MOST_POSITIVE_FIX) + return(MAKE_FIXNUM(y)); + if (s == -1 && y <= MOST_POSITIVE_FIX + 1) + return(MAKE_FIXNUM(-y)); + return big_register_copy(x); +} + +/* + * Different from mpz_init since we initialize with NULL limbs + */ + +cl_object +big_alloc(int size) +{ + volatile cl_object x = alloc_object(t_bignum); + if (size <= 0) + error("negative or zero size for bignum in big_alloc"); + x->big.big_dim = size; + x->big.big_size = 0; + x->big.big_limbs = alloc_atomic_align(size * sizeof(mp_limb_t), sizeof(mp_limb_t)); + return(x); +} + +cl_object +bignum1(int val) +{ + volatile cl_object z = alloc_object(t_bignum); + mpz_init_set_si(z->big.big_num, val); + return(z); +} + +cl_object +bignum2(mp_limb_t hi, mp_limb_t lo) +{ + cl_object z; + + z = big_alloc(2); + z->big.big_size = 2; + z->big.big_limbs[0] = lo; + z->big.big_limbs[1] = hi; + return(z); +} + +cl_object +big_copy(cl_object x) +{ + volatile cl_object y = alloc_object(t_bignum); + mpz_init_set(y->big.big_num, x->big.big_num); + return(y); +} + +/* + big_zerop(x) tells whether bignum x is zero or not. + +#define big_zerop(x) (mp_size(x->big.big_num) == 0) +*/ + +/* + big_sign(x) returns + something < 0 if x < 0 + 0 if x = 0 + something > 0 if x > 0. + +#define big_sign(x) (x->big.big_size) +*/ + +/* + big_compare(x, y) returns + -1 if x < y + 0 if x = y + 1 if x > y. + +#define big_compare(x, y) mpz_cmp(x->big.big_num, y->big.big_num) +*/ + +/* + big_complement(x) destructively takes + the complement of bignum x. + +#define big_complement(x) mpz_neg(x->big.big_num, x->big.num); +*/ + +/* + big_minus(x) returns the complement of bignum x. +*/ +cl_object +big_minus(cl_object x) +{ + volatile cl_object y = big_copy(x); + mpz_neg(y->big.big_num, y->big.big_num); + return y; +} + +/* + big_add_ui(x, i) destructively adds non-negative int i + to bignum x. + I should be non-negative. + + mpz_add_ui(x->big.big_num, x->big.big_num, i) +*/ + +/* + big_sub_ui(x, i) destructively subtracts non-negative int i + from bignum x. + I should be non-negative. + + mpz_sub_ui(x->big.big_num, x->big.big_num, i) +*/ + +/* + big_mul_ui(x, i) destructively multiplies non-negative bignum x + by non-negative int i. + I should be non-negative. + X should be non-negative. + + mpn_mul(&x->big.big_limbs, &x->big.big_limbs, x->big.big_size, &i, 1) +*/ + +/* + big_div_ui(x, i) destructively divides non-negative bignum x + by positive int i. + X will hold the remainder of the division. + div_int_big(i, x) returns the remainder of the division. + I should be positive. + X should be non-negative. + + mp_limb_t q[x->big.big_size]; + mpn_div(q, &x->big.big_limbs, &x->big.big_size, &i, 1), x +*/ + +/* + big_plus(x, y) returns the sum of bignum x and bignum y. + X and y may be any bignum. +*/ +cl_object +big_plus(cl_object x, cl_object y) +{ + volatile cl_object z = big_register0_get(); + mpz_add(z->big.big_num, x->big.big_num, y->big.big_num); + return(big_register_copy(z)); +} + +cl_object +big_normalize(cl_object x) +{ + int s = x->big.big_size; + mp_limb_t y; + if (s == 0) + return(MAKE_FIXNUM(0)); + y = x->big.big_limbs[0]; + if (s == 1 && y <= MOST_POSITIVE_FIX) + return(MAKE_FIXNUM(y)); + if (s == -1 && y <= MOST_POSITIVE_FIX + 1) + return(MAKE_FIXNUM(-y)); + return(x); +} + +static void * +mp_alloc(size_t size) +{ + return alloc_atomic_align(size, sizeof(mp_limb_t)); +} + +static void * +mp_realloc(void *ptr, size_t osize, size_t nsize) +{ + void *p = alloc_atomic_align(nsize, sizeof(mp_limb_t)); + memcpy(p, ptr, osize); + return p; +} + +static void +mp_free(void *ptr, size_t size) +{ + /*dealloc(ptr,size);*/ +} + +void +init_big(void) +{ + int i; + for (i = 0; i < 3; i++) { + bignum_register[i] = alloc_object(t_bignum); + register_root(&bignum_register[i]); + big_register_free(bignum_register[i]); + } + mp_set_memory_functions(mp_alloc, mp_realloc, mp_free); +} diff --git a/src/c/bind.d b/src/c/bind.d new file mode 100644 index 000000000..a31f0595d --- /dev/null +++ b/src/c/bind.d @@ -0,0 +1,126 @@ +/* + bind.c -- Lambda bindings. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +#define NOT_YET 10 +#define FOUND 11 +#define NOT_KEYWORD 1 + +void +parse_key( + int narg, /* number of actual args */ + cl_object *args, /* actual args */ + int nkey, /* number of keywords */ + cl_object *keys, /* keywords for the function */ + cl_object *vars, /* where to put values (vars[0..nkey-1]) + and suppliedp (vars[nkey..2*nkey-1]) */ + cl_object rest, /* rest variable or NULL */ + bool allow_other_keys) /* whether other key are allowed */ +{ cl_object *p; + int i; + cl_object k; + + /* fill in the rest arg list */ + if (rest != OBJNULL) + for (i = narg, p = args; i > 0; i--) { + CAR(rest) = *p++; + rest = CDR(rest); + } + + for (i = 0; i < 2*nkey; i++) + vars[i] = Cnil; /* default values: NIL, supplied: NIL */ + if (narg <= 0) return; + + /* scan backwards, so that if a keyword is duplicated, first one is used */ + args = args + narg; + top: + while (narg >= 2) { + args = args - 2; + k = args[0]; + for (i = 0; i < nkey; i++) { + if (keys[i] == k) { + vars[i] = args[1]; + vars[nkey+i] = Ct; + narg = narg-2; + goto top; + } + } + /* the key is a new one */ + if (allow_other_keys) + narg = narg-2; + else { + /* look for :allow-other-keys t */ + for ( i = narg-2, p = args; i >= 0; i -= 2, p -=2) + if (*p == Kallow_other_keys) { + allow_other_keys = (p[1] != Cnil); break; + } + if (allow_other_keys) narg = narg-2; + else FEerror("Unrecognized key ~a", 1, k); + } + } + if (narg != 0) FEerror("Odd number of keys", 0); +} + +/* Used in compiled macros */ +void +check_other_key(cl_object l, int n, ...) +{ + cl_object other_key = OBJNULL; + cl_object k; + int i; + bool allow_other_keys = FALSE; + va_list ap; + va_start(ap, n); /* extracting arguments */ + + for (; !endp(l); l = CDDR(l)) { + k = CAR(l); + if (!keywordp(k)) + FEerror("~S is not a keyword.", 1, k); + if (endp(CDR(l))) + FEerror("Odd number of arguments for keywords.", 0); + if (k == Kallow_other_keys && CADR(l) != Cnil) { + allow_other_keys = TRUE; + } else { +#ifndef NO_ARG_ARRAY + cl_object *ktab = (cl_object *)ap; + for (i = 0; i < n; i++) + if (ktab[i] == k) { + ktab[i] = Cnil; /* remember seen */ + break; + } + if (i >= n) other_key = k; +#else + Rewrite this! +#endif NO_ARG_ARRAY + } + } + if (other_key != OBJNULL && !allow_other_keys) + FEerror("The keyword ~S is not allowed or is duplicated.", + 1, other_key); +} + +void +init_bind(void) +{ + make_constant("LAMBDA-LIST-KEYWORDS", + list(8, SAoptional, SArest, SAkey, SAallow_other_keys, SAaux, + make_ordinary("&WHOLE"), make_ordinary("&ENVIRONMENT"), make_ordinary("&BODY"))); + + make_constant("LAMBDA-PARAMETERS-LIMIT", MAKE_FIXNUM(64)); +} diff --git a/src/c/cfun.d b/src/c/cfun.d new file mode 100644 index 000000000..603941bf1 --- /dev/null +++ b/src/c/cfun.d @@ -0,0 +1,259 @@ +/* + cfun.c -- Compiled functions. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include /* for memmove() */ + +#ifdef PDE +extern cl_object Sdefun, Sdefmacro; +#endif PDE + +static void record_fun_entry (cl_object sym, void *addr); + +cl_object +make_cfun(cl_object (*self)(), cl_object name, cl_object cblock) +{ + cl_object cf; + + cf = alloc_object(t_cfun); + cf->cfun.entry = self; + cf->cfun.name = name; + cf->cfun.block = cblock; + return(cf); +} + +cl_object +make_cclosure(cl_object (*self)(), cl_object env, cl_object block) +{ + cl_object cc; + + cc = alloc_object(t_cclosure); + cc->cclosure.entry = self; + cc->cclosure.env = env; + cc->cclosure.block = block; + return(cc); +} + +void +MF(cl_object sym, cl_object (*self)(), cl_object block) +{ + cl_object cf; + + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + if (sym->symbol.isform && sym->symbol.mflag) + sym->symbol.isform = FALSE; + clear_compiler_properties(sym); +#ifndef RUNTIME + record_fun_entry(sym, self); +#endif +#ifdef PDE + record_source_pathname(sym, Sdefun); +#endif PDE + cf = alloc_object(t_cfun); + cf->cfun.entry = self; + cf->cfun.name = sym; + cf->cfun.block = block; + SYM_FUN(sym) = cf; + sym->symbol.mflag = FALSE; +} + +void +MM(cl_object sym, cl_object (*self)(), cl_object block) +{ + cl_object cf; + + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + if (sym->symbol.isform && sym->symbol.mflag) + sym->symbol.isform = FALSE; + clear_compiler_properties(sym); +#ifndef RUNTIME + record_fun_entry(sym, self); +#endif +#ifdef PDE + record_source_pathname(sym, Sdefmacro); +#endif PDE + cf = alloc_object(t_cfun); + cf->cfun.entry = self; + cf->cfun.name = sym; + cf->cfun.block = block; + SYM_FUN(sym) = cf; + sym->symbol.mflag = TRUE; +} + +cl_object +make_function(char *s, cl_object (*f)()) +{ + cl_object x; + + x = make_ordinary(s); + SYM_FUN(x) = make_cfun(f, x, NULL); + x->symbol.mflag = FALSE; +#ifndef RUNTIME + record_fun_entry(x, f); +#endif + return(x); +} + +cl_object +make_si_function(char *s, cl_object (*f)()) +{ + cl_object x; + + x = make_si_ordinary(s); + SYM_FUN(x) = make_cfun(f, x, NULL); + x->symbol.mflag = FALSE; +#ifndef RUNTIME + record_fun_entry(x, f); +#endif + return(x); +} + +@(defun si::compiled_function_name (fun) + cl_object output; +@ + switch(type_of(fun)) { + case t_bytecodes: + output = fun->bytecodes.data[0]; break; + case t_cfun: + output = fun->cfun.name; break; + case t_cclosure: + output = Cnil; break; + default: + FEerror("~S is not a compiled-function.", 1, fun); + } + @(return output) +@) + +@(defun si::compiled_function_block (fun) + cl_object output; +@ + switch(type_of(fun)) { + case t_cfun: + output = fun->cfun.block; break; + case t_cclosure: + output = fun->cclosure.block; break; + default: + FEerror("~S is not a compiled-function.", 1, fun); + } + @(return output) +@) + + +#ifndef RUNTIME + +#define FUN_TABLE_INC 256 +void **function_entry_table; +int function_entries_max; +int function_entries; + +/*---------------------------------------------------------------------- + * fun_entry_search -- + * function_entry_table is an array containing alternated addr, sym values + * sorted in increasing addr value. + * Result: + * the index of the largest addr which is smaller than key + * -2 if no such addr is present + *---------------------------------------------------------------------- + */ +static int +fun_entry_search(char *key) +{ + void **table = function_entry_table; + int len = function_entries; + int low = 0; + int high = len; + int mid, probe; + char *entry; + if (len == 0) + return(-2); + while (TRUE) { + mid = (low + high) / 2; + probe = mid * 2; + entry = (char *)table[probe]; + if (entry == key) + return(probe); + if (entry < key) { + if (mid + 1 == len || (char*)table[probe+2] > key) + return(probe); + else + low = mid; + } else { + if (probe == 0) + return(-2); + else + high = mid; + } + } +} + +/* + *---------------------------------------------------------------------- + * record_fun_entry -- + * records the code start of function bound to symbol, so that + * one can determine which function is executing + * + *---------------------------------------------------------------------- + */ +static void +record_fun_entry(cl_object sym, void *addr) +{ + cl_object def; + register int i, end; + + end = 2*function_entries; + def = SYM_FUN(sym); + if (def != OBJNULL && type_of(def) == t_cfun) { + /* clear previous definition */ + void *prevaddr = (void *)def->cfun.entry; + i = fun_entry_search(prevaddr); + if (i >= 0 && function_entry_table[i] == prevaddr) { + function_entries--; + end -= 2; + memmove(&function_entry_table[i], &function_entry_table[i+2], + sizeof(void *) * (end - i)); + } + } + i = fun_entry_search(addr); + if (i < 0 || function_entry_table[i] != (char*)addr) { + if (2*function_entries_max == end) { + function_entries_max += FUN_TABLE_INC; + function_entry_table = realloc(function_entry_table, + 2 * function_entries_max * sizeof(void *)); + } + i += 2; + memmove(&function_entry_table[i+2], &function_entry_table[i], + sizeof(void *) * (end - i)); + function_entries++; + } + function_entry_table[i++] = (char *)addr; + function_entry_table[i++] = (char *)sym; +} + +cl_object +get_function_entry(void *addr) +{ + int i; + i = fun_entry_search(addr); + if (i >= 0) + return((cl_object)function_entry_table[i+1]); + else + return(OBJNULL); +} + +#endif RUNTIME diff --git a/src/c/character.d b/src/c/character.d new file mode 100644 index 000000000..d9609a627 --- /dev/null +++ b/src/c/character.d @@ -0,0 +1,464 @@ +/* + character.d -- Character routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include + +/******************************* EXPORTS ******************************/ + +cl_object STreturn; +cl_object STspace; +cl_object STrubout; +cl_object STpage; +cl_object STtab; +cl_object STbackspace; +cl_object STlinefeed; +cl_object STnewline; +cl_object STnull; + +/******************************* ------- ******************************/ + +cl_fixnum +char_code(cl_object c) +{ + if (CHARACTERP(c)) + return CHAR_CODE(c); + FEtype_error_character(c); +} + +@(defun standard_char_p (c) + cl_fixnum i; +@ + /* INV: char_code() checks the type */ + i = char_code(c); + if ((' ' <= i && i < '\177') || i == '\n') + @(return Ct) + @(return Cnil) +@) + +@(defun graphic_char_p (c) + cl_fixnum i; +@ + /* INV: char_code() checks the type */ + i = char_code(c); + if (' ' <= i && i < '\177') /* ' ' < '\177' ??? Beppe*/ + @(return Ct) + @(return Cnil) +@) + +@(defun alpha_char_p (c) + cl_fixnum i; +@ + /* INV: char_code() checks the type */ + i = char_code(c); + if (isalpha(i)) + @(return Ct) + else + @(return Cnil) +@) + +@(defun upper_case_p (c) +@ + /* INV: char_code() checks the type */ + if (isupper(char_code(c))) + @(return Ct) + @(return Cnil) +@) + +@(defun lower_case_p (c) +@ + /* INV: char_code() checks the type */ + if (islower(char_code(c))) + @(return Ct) + @(return Cnil) +@) + +@(defun both_case_p (c) + cl_fixnum code; +@ + /* INV: char_code() checks the type */ + code = char_code(c); + @(return ((isupper(code) || islower(code)) ? Ct : Cnil)) +@) + +#define basep(d) (d <= 36) + +@(defun digit_char_p (c &optional (r MAKE_FIXNUM(10))) + cl_fixnum d; +@ + /* INV: char_code() checks `c' and fixnnint() checks `r' */ + if (type_of(r) == t_bignum) + @(return Cnil) + d = fixnnint(r); + if (!basep(d) || (d = digitp(char_code(c), d)) < 0) + @(return Cnil) + @(return MAKE_FIXNUM(d)) +@) + +/* + Digitp(i, r) returns the weight of code i + as a digit of radix r, which must be 1 < r <= 36. + If i is not a digit, -1 is returned. +*/ +int +digitp(int i, int r) +{ + if (('0' <= i) && (i <= '9') && (i < '0' + r)) + return(i - '0'); + if (('A' <= i) && (10 < r) && (i < 'A' + (r - 10))) + return(i - 'A' + 10); + if (('a' <= i) && (10 < r) && (i < 'a' + (r - 10))) + return(i - 'a' + 10); + return(-1); +} + +@(defun alphanumericp (c) + cl_fixnum i; +@ + /* INV: char_code() checks type of `c' */ + i = char_code(c); + if (isalnum(i)) + @(return Ct) + else + @(return Cnil) +@) + +@(defun char_eq (c &rest cs) + cl_fixnum i; +@ + /* INV: char_eq() checks types of `c' and `cs' */ + for (narg--, i = 0; i < narg; i++) { + if (!char_eq(c, ((cl_object *)cs)[i])) + @(return Cnil) + } + @(return Ct) +@) + +bool +char_eq(cl_object x, cl_object y) +{ + return char_code(x) == char_code(y); +} + +@(defun char_neq (&rest cs) + int i, j; +@ + /* INV: char_eq() checks types of its arguments */ + if (narg == 0) + @(return Ct) + for (i = 0; i < narg; i++) { + for (j = 0; j < i; j++) + if (char_eq(((cl_object *)cs)[j], ((cl_object *)cs)[i])) + @(return Cnil) + } + @(return Ct) +@) + +static cl_return +Lchar_cmp(int narg, int s, int t, cl_object *args) +{ + int i; + + if (narg == 0) + FEtoo_few_arguments(&narg); + for (i = 1; i < narg; i++) + if (s*char_cmp(args[i], args[i-1]) < t) + return1(Cnil); + return1(Ct); +} + +int +char_cmp(cl_object x, cl_object y) +{ + cl_fixnum cx = char_code(x); + cl_fixnum cy = char_code(y); + if (cx < cy) + return(-1); + if (cx > cy) + return(1); + return(0); +} + +cl_return +Lchar_l(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_cmp(narg, 1, 1, (cl_object *)args);} +cl_return +Lchar_g(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_cmp(narg,-1, 1, (cl_object *)args);} +cl_return +Lchar_le(int narg, ...) +{ va_list(args); va_start(args, narg); + Lchar_cmp(narg, 1, 0, (cl_object *)args);} +cl_return +Lchar_ge(int narg, ...) +{ va_list(args); va_start(args, narg); + Lchar_cmp(narg,-1, 0, (cl_object *)args);} + +@(defun char_equal (c &rest cs) + int i; +@ + /* INV: char_equal() checks the type of its arguments */ + for (narg--, i = 0; i < narg; i++) { + if (!char_equal(c, ((cl_object *)cs)[i])) + @(return Cnil) + } + @(return Ct) +@) + +bool +char_equal(cl_object x, cl_object y) +{ + cl_fixnum i = char_code(x); + cl_fixnum j = char_code(y); + + if (islower(i)) + i = toupper(i); + if (islower(j)) + j = toupper(j); + return(i == j); +} + +@(defun char_not_equal (&rest cs) + int i, j; +@ + /* INV: char_equal() checks the type of its arguments */ + for (i = 0; i < narg; i++) { + for (j = 0; j < i; j++) + if (char_equal(((cl_object *)cs)[j], ((cl_object *)cs)[i])) + @(return Cnil) + } + @(return Ct) +@) + +static cl_return +Lchar_compare(int narg, int s, int t, cl_object *args) +{ + int i; + + /* INV: char_compare() checks the types of its arguments */ + if (narg == 0) + FEtoo_few_arguments(&narg); + for (i = 1; i < narg; i++) + if (s*char_compare(args[i], args[i-1]) < t) + return1(Cnil); + return1(Ct); +} + +int +char_compare(cl_object x, cl_object y) +{ + cl_fixnum i = char_code(x); + cl_fixnum j = char_code(y); + + if (islower(i)) + i = toupper(i); + if (islower(j)) + j = toupper(j); + if (i < j) + return(-1); + else if (i == j) + return(0); + else + return(1); +} + +cl_return +Lchar_lessp(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_compare(narg, 1, 1, (cl_object *)args);} +cl_return +Lchar_greaterp(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_compare(narg,-1, 1, (cl_object *)args);} +cl_return +Lchar_not_greaterp(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_compare(narg, 1, 0, (cl_object *)args);} +cl_return +Lchar_not_lessp(int narg, ...) +{ va_list(args); va_start(args, narg); + return Lchar_compare(narg,-1, 0, (cl_object *)args);} + + +@(defun character (x) +@ + @(return coerce_to_character(x)) +@) + +cl_object +coerce_to_character(cl_object x) +{ + switch (type_of(x)) { + case t_character: + return x; + case t_symbol: + x = x->symbol.name; + case t_string: + if (x->string.fillp == 1) + return(code_char(x->string.self[0])); + default: + FEtype_error_character(x); + } +} + +@(defun char_code (c) +@ + /* INV: char_code() checks the type of `c' */ + @(return MAKE_FIXNUM(char_code(c))) +@) + +@(defun code_char (c) + cl_fixnum fc; +@ + /* INV: fixnnint() checks the type of `c' */ + if (type_of(c) == t_bignum) + @(return Cnil) + if ((fc = fixnnint(c)) >= CHCODELIM) + @(return Cnil) + @(return code_char(fc)) +@) + +@(defun char_upcase (c) + cl_fixnum code; +@ + /* INV: char_code() checks the type of `c' */ + code = char_code(c); + @(return (islower(char_code(c)) ? + code_char(toupper(char_code(c))) : + c)) +@) + +@(defun char_downcase (c) + cl_fixnum code; +@ + /* INV: char_code() checks the type of `c' */ + code = char_code(c); + @(return (isupper(char_code(c)) ? + code_char(tolower(char_code(c))) : + c)) +@) + +@(defun digit_char (w &optional (r MAKE_FIXNUM(10))) + int dw; +@ + /* INV: fixnnint() checks the types of `w' and `r' */ + if (type_of(w) == t_bignum || type_of(r) == t_bignum) + @(return Cnil) + dw = digit_weight(fixnnint(w), fixnnint(r)); + if (dw < 0) + @(return Cnil) + @(return code_char(dw)) +@) + +short +digit_weight(int w, int r) +{ + if (r < 2 || r > 36 || w < 0 || w >= r) + return(-1); + if (w < 10) + return(w + '0'); + else + return(w - 10 + 'A'); +} + +@(defun char_int (c) +@ + /* INV: char_int() checks the type of `c' */ + @(return MAKE_FIXNUM(char_int(c))) +@) + +@(defun int_char (x) +@ + /* INV: fixnnint(x) checks the type of `c' */ + if (type_of(x) == t_bignum) + @(return Cnil) + @(return int_char(fixnnint(x))) +@) + +@(defun char_name (c) +@ + /* INV: char_code() checks the type of `c' */ + switch (char_code(c)) { + case '0': + @(return STnull) + case '\r': + @(return STreturn) + case ' ': + @(return STspace) + case '\177': + @(return STrubout) + case '\f': + @(return STpage) + case '\t': + @(return STtab) + case '\b': + @(return STbackspace) + case '\n': + @(return STnewline) + } + @(return Cnil) +@) + +@(defun name_char (s) + char c; +@ + s = coerce_to_string(s); + if (string_equal(s, STreturn)) + c = '\r'; else + if (string_equal(s, STspace)) + c = ' '; else + if (string_equal(s, STrubout)) + c = '\177'; else + if (string_equal(s, STpage)) + c = '\f'; else + if (string_equal(s, STtab)) + c = '\t'; else + if (string_equal(s, STbackspace)) + c = '\b'; else + if (string_equal(s, STlinefeed) || string_equal(s, STnewline)) + c = '\n'; else + if (string_equal(s, STnull)) + c = '\000'; else + @(return Cnil) + @(return code_char(c)) +@) + +void +init_character(void) +{ + make_constant("CHAR-CODE-LIMIT", MAKE_FIXNUM(CHCODELIM)); + + STreturn = make_simple_string("RETURN"); + register_root(&STreturn); + STspace = make_simple_string("SPACE"); + register_root(&STspace); + STrubout = make_simple_string("RUBOUT"); + register_root(&STrubout); + STpage = make_simple_string("PAGE"); + register_root(&STpage); + STtab = make_simple_string("TAB"); + register_root(&STtab); + STbackspace = make_simple_string("BACKSPACE"); + register_root(&STbackspace); + STlinefeed = make_simple_string("LINEFEED"); + register_root(&STlinefeed); + STnull = make_simple_string("NULL"); + register_root(&STnull); + STnewline = make_simple_string("NEWLINE"); + register_root(&STnewline); +} diff --git a/src/c/cinit.d b/src/c/cinit.d new file mode 100644 index 000000000..85d28ae21 --- /dev/null +++ b/src/c/cinit.d @@ -0,0 +1,53 @@ +/* + init.c -- Lisp Initialization. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +static +@(defun si::simple_toplevel () + cl_object sentence; + cl_object lex_old = lex_env; +@ + /* Simple minded top level loop */ + printf(";*** Lisp core booted ****\nECLS (Embeddable Common Lisp) %d pages\n", MAXPAGE); + fflush(stdout); +#ifdef TK + StdinResume(); +#endif + lex_new(); + while (1) { + cl_object bytecodes = Cnil; + printf("\n> "); + sentence = Lread(3, Cnil, Cnil, OBJNULL); + if (sentence == OBJNULL) + @(return); + prin1(eval(sentence, &bytecodes), Cnil); +#ifdef TK + StdinResume(); +#endif + } + lex_env = lex_old; +@) + +void +init_lisp_libs(void) +{ + SYM_VAL(Vpackage) = system_package; + SYM_VAL(Vfeatures) = CONS(make_keyword("ECLS-MIN"), SYM_VAL(Vfeatures)); +#ifdef RSYM + SYM_VAL(siVsymbol_table) = make_simple_string("ecls_min.sym"); +#endif + make_si_function("TOP-LEVEL", siLsimple_toplevel); +} diff --git a/src/c/clos.d b/src/c/clos.d new file mode 100644 index 000000000..a4c129fa5 --- /dev/null +++ b/src/c/clos.d @@ -0,0 +1,115 @@ +/* + clos.c -- CLOS bootstrap. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +cl_object class_class, class_object, class_built_in; + +/******************************* ------- ******************************/ + +cl_object siSXclass_name_hash_tableX; +cl_object Sclass; +cl_object Sbuilt_in; + +static cl_object +make_our_hash_table(cl_object test, int size) +{ + enum httest htt; + int i; + cl_object rehash_size, rehash_threshold, h; + + rehash_size = make_shortfloat(1.5); + rehash_threshold = make_shortfloat(0.7); + + if (test == Seq) + htt = htt_eq; + else if (test == Seql) + htt = htt_eql; + else if (test == Sequal) + htt = htt_equal; + + h = alloc_object(t_hashtable); + h->hash.data = NULL; /* for GC sake */ + h->hash.test = (short)htt; + h->hash.size = size; + h->hash.rehash_size = rehash_size; + h->hash.threshold = rehash_threshold; + h->hash.entries = 0; + h->hash.data = alloc_align(size * sizeof(struct hashtable_entry), sizeof(int)); + for(i = 0; i < size; i++) { + h->hash.data[i].key = OBJNULL; + h->hash.data[i].value = OBJNULL; + } + return(h); +} + +static void +clos_boot(void) +{ + + SYM_VAL(siSXclass_name_hash_tableX) = make_our_hash_table(Seq, 1024); + + /* booting Class CLASS */ + + class_class = alloc_instance(4); + register_root(&class_class); + class_class->instance.class = class_class; + CLASS_NAME(class_class) = Sclass; + CLASS_SUPERIORS(class_class) = Cnil; + CLASS_INFERIORS(class_class) = Cnil; + CLASS_SLOTS(class_class) = OBJNULL; /* filled later */ + + sethash(Sclass, SYM_VAL(siSXclass_name_hash_tableX), class_class); + + /* booting Class BUILT-IN */ + + class_built_in = alloc_instance(4); + register_root(&class_built_in); + class_built_in->instance.class = class_class; + CLASS_NAME(class_built_in) = Sbuilt_in; + CLASS_SUPERIORS(class_built_in) = CONS(class_class, Cnil); + CLASS_INFERIORS(class_built_in) = Cnil; + CLASS_SLOTS(class_built_in) = OBJNULL; /* filled later */ + + sethash(Sbuilt_in, SYM_VAL(siSXclass_name_hash_tableX), class_built_in); + + /* booting Class T (= OBJECT) */ + + class_object = alloc_instance(4); + register_root(&class_object); + class_object->instance.class = class_built_in; + CLASS_NAME(class_object) = St; + CLASS_SUPERIORS(class_object) = Cnil; + CLASS_INFERIORS(class_object) = CONS(class_class, Cnil); + CLASS_SLOTS(class_object) = Cnil; + + sethash(St, SYM_VAL(siSXclass_name_hash_tableX), class_object); + + /* complete now Class CLASS */ + CLASS_SUPERIORS(class_class) = CONS(class_object, Cnil); + CLASS_INFERIORS(class_class) = CONS(class_built_in, Cnil); +} + +void +init_clos(void) +{ + SYM_VAL(siSXclass_name_hash_tableX) = OBJNULL; + + clos_boot(); +} diff --git a/src/c/cmpaux.d b/src/c/cmpaux.d new file mode 100644 index 000000000..414945ec6 --- /dev/null +++ b/src/c/cmpaux.d @@ -0,0 +1,328 @@ +/* + cmpaux.c -- Auxiliaries used in compiled Lisp code. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +cl_object SAoptional; +cl_object SArest; +cl_object SAkey; +cl_object SAallow_other_keys; +cl_object SAaux; +cl_object Kallow_other_keys; + +cl_object +make_list(int i) +{ + cl_object x = Cnil; + while (i-- > 0) + x = CONS(Cnil, x); + return x; +} + +@(defun si::specialp (sym) +@ + @(return ((SYMBOLP(sym) && sym->symbol.stype == stp_special) ? + Ct : Cnil)) +@) + +int +ifloor(int x, int y) +{ + if (y == 0) + FEerror("Zero divizor", 0); + else if (y > 0) + if (x >= 0) + return(x/y); + else + return(-((-x+y-1))/y); + else + if (x >= 0) + return(-((x-y-1)/(-y))); + else + return((-x)/(-y)); +} + +int +imod(int x, int y) +{ + return(x - ifloor(x, y)*y); +} + +/* + * ---------------------------------------------------------------------- + * Conversions to C + * ---------------------------------------------------------------------- + */ + +char +object_to_char(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + return fix(x); + case t_bignum: + return big_to_long(x) & (CHCODELIM - 1); + case t_character: + return CHAR_CODE(x); + default: + FEerror("~S cannot be coerced to a C char.", 1, x); + } +} + +int +object_to_int(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + return fix(x); + case t_character: + return CHAR_CODE(x); + case t_bignum: + return big_to_long(x); + case t_ratio: + return number_to_double(x); + case t_shortfloat: + return sf(x); + case t_longfloat: + return lf(x); + default: + FEerror("~S cannot be coerced to a C int.", 1, x); + } +} + +char * +object_to_string(cl_object x) +{ + extern VOID *malloc(size_t size); + switch (type_of(x)) { + case t_string: + case t_symbol: + return(x->string.self); + case t_fixnum: { + char *num = malloc(12); + sprintf(num, "%ld", (long)fix(x)); + return(num); + } + case t_character: { + char *c = malloc(2); + c[0] = CHAR_CODE(x); + c[1] = '\0'; + return c; + } + case t_pathname: + return namestring(x)->string.self; + default: + FEerror("~S cannot be coerced to a C string.", 1, x); + } +} + +float +object_to_float(cl_object x) +{ + if (FIXNUMP(x)) return(fix(x)); /* Immediate fixnum */ + + switch (type_of(x)) { + /* case t_fixnum: return fix(x); */ + case t_character: + return CHAR_CODE(x); + case t_bignum: + case t_ratio: + return number_to_double(x); + case t_shortfloat: + return sf(x); + case t_longfloat: + return lf(x); + default: + FEerror("~S cannot be coerced to a C float.", 1, x); + } +} + +double +object_to_double(cl_object x) +{ + + if (FIXNUMP(x)) return(fix(x)); /* Immediate fixnum */ + + switch (type_of(x)) { + /* case t_fixnum: return fix(x); */ + case t_character: + return CHAR_CODE(x); + case t_bignum: + case t_ratio: + return number_to_double(x); + case t_shortfloat: + return sf(x); + case t_longfloat: + return lf(x); + default: + FEerror("~S cannot be coerced to a C double.", 1, x); + } +} + +int +aref_bv(cl_object x, cl_index index) +{ + index += x->vector.offset; + return ((x->vector.self.bit[index/CHAR_BIT] & (0200>>index%CHAR_BIT)) != 0); +} + +int +aset_bv(cl_object x, cl_index index, int value) +{ + index += x->vector.offset; + if (value == 0) + x->vector.self.bit[index/CHAR_BIT] &= ~(0200>>index%CHAR_BIT); + else + x->vector.self.bit[index/CHAR_BIT] |= 0200>>index%CHAR_BIT; + return value; +} + +void +throw(cl_object tag) +{ + frame_ptr fr = frs_sch_catch(tag); + if (fr == NULL) + FEcontrol_error("THROW: The catch ~S is undefined.", 1, tag); + unwind(fr, tag); +} + +void +return_from(cl_object block_id, cl_object block_name) +{ + frame_ptr fr = frs_sch(block_id); + if (fr == NULL) + FEcontrol_error("RETURN-FROM: The block ~S with id ~S is missing.", + 2, block_name, block_id); + unwind(fr, block_name); +} + +void +go(cl_object tag_id, cl_object label) +{ + frame_ptr fr = frs_sch(tag_id); + if (fr == NULL) + FEcontrol_error("GO: The tagbody ~S is missing.", 1, tag_id); + unwind(fr, label); +} + +#define NOT_YET 10 +#define FOUND 11 +#define NOT_KEYWORD 1 + +void +parse_key( + int narg, /* number of actual args */ + cl_object *args, /* actual args */ + int nkey, /* number of keywords */ + cl_object *keys, /* keywords for the function */ + cl_object *vars, /* where to put values (vars[0..nkey-1]) + and suppliedp (vars[nkey..2*nkey-1]) */ + cl_object rest, /* rest variable or NULL */ + bool allow_other_keys) /* whether other key are allowed */ +{ cl_object *p; + int i; + cl_object k; + + /* fill in the rest arg list */ + if (rest != OBJNULL) + for (i = narg, p = args; i > 0; i--) { + CAR(rest) = *p++; + rest = CDR(rest); + } + + for (i = 0; i < 2*nkey; i++) + vars[i] = Cnil; /* default values: NIL, supplied: NIL */ + if (narg <= 0) return; + + /* scan backwards, so that if a keyword is duplicated, first one is used */ + args = args + narg; + top: + while (narg >= 2) { + args = args - 2; + k = args[0]; + for (i = 0; i < nkey; i++) { + if (keys[i] == k) { + vars[i] = args[1]; + vars[nkey+i] = Ct; + narg = narg-2; + goto top; + } + } + /* the key is a new one */ + if (allow_other_keys) + narg = narg-2; + else { + /* look for :allow-other-keys t */ + for ( i = narg-2, p = args; i >= 0; i -= 2, p -=2) + if (*p == Kallow_other_keys) { + allow_other_keys = (p[1] != Cnil); break; + } + if (allow_other_keys) narg = narg-2; + else FEprogram_error("Unrecognized key ~a", 1, k); + } + } + if (narg != 0) FEprogram_error("Odd number of keys", 0); +} + +/* Used in compiled macros */ +void +check_other_key(cl_object l, int n, ...) +{ + cl_object other_key = OBJNULL; + cl_object k; + int i; + bool allow_other_keys = FALSE; + va_list ap; + va_start(ap, n); /* extracting arguments */ + + for (; !endp(l); l = CDDR(l)) { + k = CAR(l); + if (!keywordp(k)) + FEprogram_error("~S is not a keyword.", 1, k); + if (endp(CDR(l))) + FEprogram_error("Odd number of arguments for keywords.",0); + if (k == Kallow_other_keys && CADR(l) != Cnil) { + allow_other_keys = TRUE; + } else { +#ifndef NO_ARG_ARRAY + cl_object *ktab = (cl_object *)ap; + for (i = 0; i < n; i++) + if (ktab[i] == k) { + ktab[i] = Cnil; /* remember seen */ + break; + } + if (i >= n) other_key = k; +#else + Rewrite this! +#endif NO_ARG_ARRAY + } + } + if (other_key != OBJNULL && !allow_other_keys) + FEprogram_error("The keyword ~S is not allowed or is duplicated.", + 1, other_key); +} + +void +init_cmpaux(void) +{ + make_constant("LAMBDA-LIST-KEYWORDS", + list(8, SAoptional, SArest, SAkey, SAallow_other_keys, SAaux, + make_ordinary("&WHOLE"), make_ordinary("&ENVIRONMENT"), make_ordinary("&BODY"))); + + make_constant("LAMBDA-PARAMETERS-LIMIT", MAKE_FIXNUM(64)); +} diff --git a/src/c/compiler.d b/src/c/compiler.d new file mode 100644 index 000000000..4a5835797 --- /dev/null +++ b/src/c/compiler.d @@ -0,0 +1,2100 @@ +/* + compiler.c -- Bytecode compiler +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +/********************* EXPORTS *********************/ + +cl_object siSlambda_block; +cl_object Sdeclare; +cl_object Sdefun; +cl_object Scompile, Sload, Seval, Sprogn, Swarn, Stypep, Sotherwise; +cl_object Kexecute, Kcompile_toplevel, Kload_toplevel; +cl_object siVinhibit_macro_special; + +cl_object SAoptional; +cl_object SArest; +cl_object SAkey; +cl_object SAallow_other_keys; +cl_object SAaux; + +cl_object Kallow_other_keys; + +cl_object bytecodes; + +/********************* PRIVATE ********************/ + +static cl_index asm_begin(void); +static cl_object asm_end(cl_index); +static void asm_clear(cl_index); +static void asm_grow(void); +static void asm1(register cl_object op); +static void asm_op(register int n); +static void asm_list(register cl_object l); +static void asmn(int narg, ...); +static void asm_at(register cl_index where, register cl_object what); +static cl_index asm_jmp(register int op); +static void asm_complete(register int op, register cl_index original); +static cl_index current_pc(); +static void set_pc(cl_index pc); +static cl_object asm_ref(register cl_index where); + +static void c_and(cl_object args); +static void c_block(cl_object args); +static void c_case(cl_object args); +static void c_catch(cl_object args); +static void c_cond(cl_object args); +static void c_do(cl_object args); +static void c_doa(cl_object args); +static void c_dolist(cl_object args); +static void c_dotimes(cl_object args); +static void c_eval_when(cl_object args); +static void c_flet(cl_object args); +static void c_function(cl_object args); +static void c_go(cl_object args); +static void c_if(cl_object args); +static void c_labels(cl_object args); +static void c_let(cl_object args); +static void c_leta(cl_object args); +static void c_macrolet(cl_object args); +static void c_multiple_value_bind(cl_object args); +static void c_multiple_value_call(cl_object args); +static void c_multiple_value_prog1(cl_object args); +static void c_multiple_value_setq(cl_object args); +static void c_nth_value(cl_object args); +static void c_or(cl_object args); +static void c_progv(cl_object args); +static void c_psetq(cl_object args); +static void c_values(cl_object args); +static void c_setq(cl_object args); +static void c_return(cl_object args); +static void c_return_from(cl_object args); +static void c_symbol_macrolet(cl_object args); +static void c_tagbody(cl_object args); +static void c_throw(cl_object args); +static void c_unless(cl_object args); +static void c_unwind_protect(cl_object args); +static void c_when(cl_object args); +static void compile_body(cl_object args); +static void compile_form(cl_object args, bool push); + +static void FEillegal_variable_name(cl_object) __attribute__((noreturn)); +static void FEill_formed_input() __attribute__((noreturn)); + +/* -------------------- SAFE LIST HANDLING -------------------- */ + +static cl_object +pop(cl_object *l) { + cl_object head, list = *l; + if (ATOM(list)) + FEill_formed_input(); + head = CAR(list); + *l = CDR(list); + return head; +} + +static cl_object +pop_maybe_nil(cl_object *l) { + cl_object head, list = *l; + if (list == Cnil) + return Cnil; + if (ATOM(list)) + FEill_formed_input(); + head = CAR(list); + *l = CDR(list); + return head; +} + +/* ------------------------------ ASSEMBLER ------------------------------ */ + +static cl_index +asm_begin(void) { + /* Save beginning of bytecodes for this session */ + return current_pc(); +} + +static void +asm_clear(cl_index beginning) { + cl_index i; + /* Remove data from this session */ + bytecodes->vector.fillp = beginning; +} + +static cl_object +asm_end(cl_index beginning) { + cl_object new_bytecodes; + cl_index length, bytes, i; + + /* Save bytecodes from this session in a new vector */ + length = current_pc() - beginning; + bytes = length * sizeof(cl_object); + new_bytecodes = alloc_object(t_bytecodes); + new_bytecodes->bytecodes.lex = Cnil; + new_bytecodes->bytecodes.data = alloc(bytes); + new_bytecodes->bytecodes.size = length; + memcpy(new_bytecodes->bytecodes.data, + &bytecodes->vector.self.t[beginning], + bytes); + + asm_clear(beginning); + return new_bytecodes; +} + +static void +asm_grow(void) { + cl_object *old_data = bytecodes->vector.self.t; + cl_index old_size = bytecodes->vector.fillp; + bytecodes->vector.dim += 128; + array_allocself(bytecodes); + memcpy(bytecodes->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +asm1(register cl_object op) { + int where = bytecodes->vector.fillp; + if (where >= bytecodes->vector.dim) + asm_grow(); + bytecodes->vector.self.t[where] = op; + bytecodes->vector.fillp++; +} + +static void +asm_op(register int n) { + asm1(MAKE_FIXNUM(n)); +} + +static void +asm_op2(register int code, register cl_fixnum n) { + cl_object op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEprogram_error("Argument to bytecode is too large", 0); + else + asm1(new_op); +} + +static inline cl_object +make_op(int code) { + return MAKE_FIXNUM(code); +} + +static cl_object +make_op2(int code, cl_fixnum n) { + cl_object volatile op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEprogram_error("Argument to bytecode is too large", 0); + return new_op; +} + +static void +asm_insert(cl_fixnum where, cl_object op) { + cl_fixnum end = bytecodes->vector.fillp; + if (where > end) + FEprogram_error("asm1_insert: position out of range", 0); + if (end >= bytecodes->vector.dim) + asm_grow(); + memmove(&bytecodes->vector.self.t[where+1], + &bytecodes->vector.self.t[where], + (end - where) * sizeof(cl_object)); + bytecodes->vector.fillp++; + bytecodes->vector.self.t[where] = op; +} + +static void +asm_list(register cl_object l) { + if (ATOM(l)) + asm1(l); + while(!endp(l)) { + asm1(CAR(l)); + l = CDR(l); + } +} + +static void +asmn(int narg, ...) { + va_list args; + + va_start(args, narg); + while (narg-- > 0) + asm1(va_arg(args, cl_object)); +} + +static void +asm_at(register cl_index where, register cl_object what) { + if (where > bytecodes->vector.fillp) + FEprogram_error("Internal error at asm_at()",0); + bytecodes->vector.self.t[where] = what; +} + +static cl_index +asm_block(void) { + cl_index output; + output = current_pc(); + asm1(MAKE_FIXNUM(0)); + return output; +} + +static cl_index +asm_jmp(register int op) { + cl_index output = current_pc(); + asm_op(op); + return output; +} + +static void +asm_complete(register int op, register cl_index original) { + cl_fixnum delta = current_pc() - original; + cl_object code = asm_ref(original); + cl_object new_code = SET_OPARG(code, delta); + if (code != MAKE_FIXNUM(op)) + FEprogram_error("Non matching codes in ASM-COMPLETE2", 0); + else if (delta < -MAX_OPARG || delta > MAX_OPARG) + FEprogram_error("Too large jump", 0); + else + asm_at(original, new_code); +} + +static cl_index +current_pc(void) { + return bytecodes->vector.fillp; +} + +static void +set_pc(cl_index pc) { + bytecodes->vector.fillp = pc; +} + +static cl_object +asm_ref(register cl_index n) { + return bytecodes->vector.self.t[n]; +} + +/* ------------------------------ COMPILER ------------------------------ */ + +typedef struct { + cl_object symbol; + const char *const name; + void (*compiler)(cl_object); +} compiler_record; + +static compiler_record database[] = { + {OBJNULL, "AND", c_and}, + {OBJNULL, "BLOCK", c_block}, + {OBJNULL, "CASE", c_case}, + {OBJNULL, "CATCH", c_catch}, + {OBJNULL, "COND", c_cond}, + {OBJNULL, "DO", c_do}, + {OBJNULL, "DO*", c_doa}, + {OBJNULL, "DOLIST", c_dolist}, + {OBJNULL, "DOTIMES", c_dotimes}, + {OBJNULL, "EVAL-WHEN", c_eval_when}, + {OBJNULL, "FLET", c_flet}, + {OBJNULL, "FUNCTION", c_function}, + {OBJNULL, "GO", c_go}, + {OBJNULL, "IF", c_if}, + {OBJNULL, "LABELS", c_labels}, + {OBJNULL, "LET", c_let}, + {OBJNULL, "LET*", c_leta}, + {OBJNULL, "MACROLET", c_macrolet}, + {OBJNULL, "MULTIPLE-VALUE-BIND", c_multiple_value_bind}, + {OBJNULL, "MULTIPLE-VALUE-CALL", c_multiple_value_call}, + {OBJNULL, "MULTIPLE-VALUE-PROG1", c_multiple_value_prog1}, + {OBJNULL, "MULTIPLE-VALUE-SETQ", c_multiple_value_setq}, + {OBJNULL, "NTH-VALUE", c_nth_value}, + {OBJNULL, "OR", c_or}, + {OBJNULL, "PROGN", compile_body}, + {OBJNULL, "PROGV", c_progv}, + {OBJNULL, "PSETQ", c_psetq}, + {OBJNULL, "RETURN", c_return}, + {OBJNULL, "RETURN-FROM", c_return_from}, + {OBJNULL, "SETQ", c_setq}, + {OBJNULL, "SYMBOL-MACROLET", c_symbol_macrolet}, + {OBJNULL, "TAGBODY", c_tagbody}, + {OBJNULL, "THROW", c_throw}, + {OBJNULL, "UNWIND-PROTECT", c_unwind_protect}, + {OBJNULL, "UNLESS", c_unless}, + {OBJNULL, "VALUES", c_values}, + {OBJNULL, "WHEN", c_when}, + {OBJNULL, "", c_when} +}; + +/* ----------------- LEXICAL ENVIRONMENT HANDLING -------------------- */ + +static void +FEillegal_variable_name(cl_object v) +{ + FEprogram_error("Not a valid variable name ~S.", 1, v); +} + +static void +FEill_formed_input() +{ + FEprogram_error("Unproper list handled to the compiler.", 0); +} + +static void +c_register_var(register cl_object var, bool special) +{ + CAR(lex_env) = CONS(CONS(var, special? Sspecial : Cnil), CAR(lex_env)); +} + +static bool +special_variablep(register cl_object var, register cl_object specials) +{ + return ((var->symbol.stype == stp_special) || member_eq(var, specials)); +} + +static void +c_pbind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_PBINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_PBIND); + } + asm1(var); +} + +static void +c_bind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_BINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_BIND); + } + asm1(var); +} + +static void +compile_setq(int op, cl_object var) +{ + cl_object ndx; + + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm_op(op); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEassignment_to_constant(var); + else if (op == OP_SETQ) + asm_op(OP_SETQS); /* Special variable */ + else + asm_op(OP_PSETQS); /* Special variable */ + asm1(var); +} + +/* -------------------- THE COMPILER -------------------- */ + +static void +c_and(cl_object args) { + if (Null(args)) { + asm1(Ct); + return; + } else if (ATOM(args)) { + FEill_formed_input(); + } else { + compile_form(pop(&args),FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JNIL); + c_and(args); + asm_complete(OP_JNIL, label); + } + } +} + +/* + The OP_BLOCK operator encloses several forms within a block + named BLOCK_NAME, thus catching any OP_RETFROM whose argument + matches BLOCK_NAME. The end of this block is marked both by + the OP_EXIT operator and the LABELZ which is packed within + the OP_BLOCK operator. + + [OP_BLOCK + labelz] + block_name + .... + OP_EXIT + labelz: ... +*/ + +static void +c_block(cl_object body) { + cl_object name = pop(&body); + cl_index labelz = asm_jmp(OP_BLOCK); + if (!SYMBOLP(name)) + FEprogram_error("BLOCK: Not a valid block name, ~S", 1, name); + asm1(name); + compile_body(body); + asm_op(OP_EXIT); + asm_complete(OP_BLOCK, labelz); +} + +/* + There are several ways to invoke functions and to handle the + output arguments. These are + + [OP_CALL + nargs] + function_name + + [OP_PCALL + nargs] + function_name + + [OP_FCALL + nargs] + + [OP_PFCALL + nargs] + + OP_CALL and OP_FCALL leave all arguments in the VALUES() array, + while OP_PCALL and OP_PFCALL leave the first argument in the + stack. + + OP_CALL and OP_PCALL use the following symbol to retrieve the + function, while OP_FCALL and OP_PFCALL use the value in VALUES(0). + */ +static void +c_call(cl_object args, bool push) { + cl_object name; + cl_index nargs; + + name = pop(&args); + for (nargs = 0; !endp(args); nargs++) { + compile_form(pop(&args),TRUE); + } + if (ATOM(name)) { + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(name); + } else if (CAR(name) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(name))); + asm_op2(push? OP_PFCALL : OP_FCALL, nargs); + } else { + cl_object aux = setf_namep(name); + if (aux == OBJNULL) + FEprogram_error("FUNCALL: Invalid function name ~S.", + 1, name); + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(aux); + } +} + +static void +perform_c_case(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label1, label2; + + if (Null(args)) { + asm_op(OP_NOP); + return; + } + + clause = pop(&args); + if (ATOM(clause)) + FEprogram_error("CASE: Illegal clause ~S.",1,clause); + test = pop(&clause); + if (Sotherwise == test || test == Ct) { + compile_body(clause); + } else { + cl_index labeln, labelz; + if (CONSP(test)) { + cl_index n = length(test); + while (n > 1) { + cl_object v = pop(&test); + cl_fixnum jump = (n--) * 2; + asm_op2(OP_JEQ, jump); + asm1(v); + } + test = CAR(test); + } + labeln = asm_jmp(OP_JNEQ); + asm1(test); + compile_body(clause); + labelz = asm_jmp(OP_JMP); + asm_complete(OP_JNEQ, labeln); + perform_c_case(args); + asm_complete(OP_JMP, labelz); + } +} + +static void +c_case(cl_object clause) { + compile_form(pop(&clause), FALSE); + perform_c_case(clause); +} + +/* + The OP_CATCH takes the object in VALUES(0) and uses it to catch + any OP_THROW operation which uses that value as argument. If a + catch occurs, or when all forms have been properly executed, it + jumps to LABELZ. LABELZ is packed within the OP_CATCH operator. + [OP_CATCH + labelz] + ... + "forms to be caught" + ... + OP_EXIT + labelz: ... +*/ + +static void +c_catch(cl_object args) { + cl_index labelz; + + /* Compile evaluation of tag */ + compile_form(pop(&args), FALSE); + + /* Compile jump point */ + labelz = asm_jmp(OP_CATCH); + + /* Compile body of CATCH */ + compile_body(args); + asm_op(OP_EXIT); + asm_complete(OP_CATCH, labelz); +} + +/* + There are three operators which perform explicit jumps, but + almost all other operators use labels in one way or + another. + + 1) Jumps are always relative to the place where the jump label + is retrieved so that if the label is in vector[0], then the + destination is roughly vector + vector[0]. + + 2) There are two types of labels, "packed labels" and "simple + labels". The first ones are packed in the upper bits of an + operator so that + destination = vector + vector[0]>>16 + Simple labels take the whole word and thus + destination = vector + fix(vector[0]) + + 3) The three jump forms are + + [OP_JMP + label] ; Unconditional jump + [OP_JNIL + label] ; Jump if VALUES(0) == Cnil + [OP_JT + label] ; Jump if VALUES(0) != Cnil + + It is important to remark that both OP_JNIL and OP_JT truncate + the values stack, so that always NValues = 1 after performing + any of these operations. +*/ +static void +c_cond(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label_nil, label_exit; + + clause = pop(&args); + if (ATOM(clause)) + FEprogram_error("COND: Illegal clause ~S.",1,clause); + test = pop(&clause); + if (Ct == test) { + /* Default sentence. If no forms, just output T. */ + if (Null(clause)) + compile_form(Ct, FALSE); + else + compile_body(clause); + } else { + /* Compile the test. If no more forms, just output + the first value (this is guaranteed by OP_JNIL */ + compile_form(test, FALSE); + label_nil = asm_jmp(OP_JNIL); + if (!Null(clause)) + compile_body(clause); + if (Null(args)) + asm_complete(OP_JNIL, label_nil); + else { + label_exit = asm_jmp(OP_JMP); + asm_complete(OP_JNIL, label_nil); + c_cond(args); + asm_complete(OP_JMP, label_exit); + } + } +} + +/* The OP_DO operator saves the lexical environment and establishes + a NIL block to execute the enclosed forms, which are typically + like the ones shown below. At the exit of the block, either by + means of a OP_RETFROM jump or because of normal termination, + the lexical environment is restored, and all bindings undone. + + [OP_DO + labelz] + labelz + ... ; bindings + labelb: ... ; body + ... ; stepping forms + labelt: ... ; test form + [JNIL + label] + ... ; output form + OP_EXIT + labelz: + +*/ +static void +c_do_doa(int op, cl_object args) { + cl_object bindings, test, specials, body, l; + cl_object stepping = Cnil, vars = Cnil; + cl_index labelb, labelt, labelz; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = pop(&args); + test = pop(&args); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + labelz = asm_jmp(OP_DO); + + /* Compile initial bindings */ + if (length(bindings) == 1) + op = OP_BIND; + for (l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!endp(aux)) + stepping = CONS(CONS(var,pop(&aux)),stepping); + if (!Null(aux)) + FEprogram_error("LET: Ill formed declaration.", 0); + } + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + + /* Jump to test */ + labelt = asm_jmp(OP_JMP); + + /* Compile body */ + labelb = current_pc(); + c_tagbody(body); + + /* Compile stepping clauses */ + if (length(stepping) == 1) + op = OP_BIND; + for (vars = Cnil, stepping=nreverse(stepping); !endp(stepping); ) { + cl_object pair = pop(&stepping); + cl_object var = CAR(pair); + cl_object value = CDR(pair); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); + + /* Compile test */ + asm_complete(OP_JMP, labelt); + compile_form(pop(&test), FALSE); + asm_op2(OP_JNIL, labelb - current_pc()); + + /* Compile output clauses */ + compile_body(test); + asm_op(OP_EXIT); + + /* Compile return point of block */ + asm_complete(OP_DO, labelz); + + lex_env = lex_old; +} + + +static void +c_doa(cl_object args) { + c_do_doa(OP_BIND, args); +} + +static void +c_do(cl_object args) { + c_do_doa(OP_PBIND, args); +} + +/* + The OP_DOLIST & OP_DOTIMES operators save the lexical + environment and establishes a NIL block to execute the + enclosed forms, which iterate over the elements in a list or + over a range of integer numbers. At the exit of the block, + either by means of a OP_RETFROM jump or because of normal + termination, the lexical environment is restored, and all + bindings undone. + + [OP_DOTIMES/OP_DOLIST + labelz] + ... ; bindings + [OP_EXIT + labelo] + ... ; body + ... ; stepping forms + OP_EXIT + labelo: ... ; output form + OP_EXIT + labelz: + + */ + +static void +c_dolist_dotimes(int op, cl_object args) { + cl_object head = pop(&args); + cl_object var = pop(&head); + cl_object list = pop(&head); + cl_object specials, body; + cl_index labelz, labelo; + cl_object lex_old = lex_env; + lex_copy(); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + + /* Compute list and enter loop */ + compile_form(list, FALSE); + labelz = asm_jmp(op); + + /* Initialize the variable */ + compile_form((op == OP_DOLIST)? Cnil : MAKE_FIXNUM(0), FALSE); + c_bind(var, specials); + labelo = asm_jmp(OP_EXIT); + + /* Variable assignment and iterated body */ + compile_setq(OP_SETQ, var); + c_tagbody(body); + asm_op(OP_EXIT); + + /* Output */ + asm_complete(OP_EXIT, labelo); + if (CDR(head) != Cnil) + FEprogram_error("DOLIST: Too many output forms.", 0); + if (Null(head)) + compile_body(Cnil); + else { + compile_setq(OP_SETQ, var); + compile_form(pop(&head), FALSE); + } + asm_op(OP_EXIT); + + /* Exit point for block */ + asm_complete(op, labelz); + + lex_env = lex_old; +} + + +static void +c_dolist(cl_object args) { + c_dolist_dotimes(OP_DOLIST, args); +} + +static void +c_dotimes(cl_object args) { + c_dolist_dotimes(OP_DOTIMES, args); +} + +static void +c_eval_when(cl_object args) { + cl_object situation = pop(&args); + + if (member_eq(Seval, situation) || member_eq(Kexecute, situation)) + compile_body(args); + else + compile_body(Cnil); +} + + +/* + The OP_FLET/OP_FLABELS operators change the lexical environment + to add a few local functions. + + [OP_FLET/OP_FLABELS + nfun] + fun1 + ... + funn + ... + OP_EXIT + labelz: +*/ +static void +c_labels_flet(int op, cl_object args) { + cl_object def_list = pop(&args); + int nfun = length(def_list); + cl_object lex_old = lex_env; + lex_copy(); + + /* Remove declarations */ + siLprocess_declarations(1, args); + args = VALUES(1); + if (nfun == 0) { + compile_body(args); + return; + } + asm_op2(op, nfun); + do { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + asm1(make_lambda(name, definition)); + } while (!endp(def_list)); + compile_body(args); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + + +static void +c_flet(cl_object args) { + c_labels_flet(OP_FLET, args); +} + + +/* + There are two operators that produce functions. The first one + is + OP_FUNCTION + symbol + which takes the function binding of SYMBOL. The second one is + OP_CLOSE + interpreted + which encloses the INTERPRETED function in the current lexical + environment. +*/ +static void +c_function(cl_object args) { + cl_object function = pop(&args); + if (!endp(args)) + FEprogram_error("FUNCTION: Too many arguments.", 0); + if (SYMBOLP(function)) { + asm_op(OP_FUNCTION); + asm1(function); + } else if (CONSP(function) && CAR(function) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(function))); + } else if (CONSP(function) && CAR(function) == siSlambda_block) { + cl_object name = CADR(function); + cl_object body = CDDR(function); + asm_op(OP_CLOSE); + asm1(make_lambda(name, body)); + } else + FEprogram_error("FUNCTION: Not a valid argument ~S.", 1, function); +} + + +static void +c_go(cl_object args) { + asm_op(OP_GO); + asm1(pop(&args)); + if (!Null(args)) + FEprogram_error("GO: Too many arguments.",0); +} + + +/* + To get an idea of what goes on + + ... ; test form + JNIL labeln + ... ; form for true case + JMP labelz + ... ; form fro nil case + labelz: +*/ +static void +c_if(cl_object form) { + cl_fixnum label_nil, label_true; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_nil = asm_jmp(OP_JNIL); + + /* Compile THEN clause */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JMP); + + /* Compile ELSE clause */ + asm_complete(OP_JNIL, label_nil); + if (!endp(form)) + compile_form(pop(&form), FALSE); + asm_complete(OP_JMP, label_true); + + if (!Null(form)) + FEprogram_error("IF: Too many arguments.", 0); +} + + +static void +c_labels(cl_object args) { + c_labels_flet(OP_LABELS, args); +} + + +/* + The OP_PUSHENV saves the current lexical environment to allow + several bindings. + OP_PUSHENV + ... ; binding forms + ... ; body + OP_EXIT + + There are four forms which perform bindings + OP_PBIND ; Bind NAME in the lexical env. using + name ; a value from the stack + OP_PBINDS ; Bind NAME as special variable using + name ; a value from the stack + OP_BIND ; Bind NAME in the lexical env. using + name ; VALUES(0) + OP_BINDS ; Bind NAME as special variable using + name ; VALUES(0) + + After a variable has been bound, there are several ways to + refer to it. + + 1) Refer to the n-th variable in the lexical environment + [SYMVAL + n] + + 2) Refer to the value of a special variable or constant + SYMVALS + name + + 3) Push the value of the n-th variable of the lexical environment + [PUSHV + n] + + 4) Push the value of a special variable or constant + PUSHVS + name +*/ + +static void +c_let_leta(int op, cl_object args) { + cl_object bindings, specials, body, l, vars; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = car(args); + siLprocess_declarations(1, CDR(args)); + body = VALUES(1); + specials = VALUES(3); + + /* Optimize some common cases */ + switch(length(bindings)) { + case 0: compile_body(body); return; + case 1: op = OP_BIND; break; + default: + } + + asm_op(OP_PUSHENV); + for (vars=Cnil, l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!Null(aux)) + FEprogram_error("LET: Ill formed declaration ~S.",0); + } + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + compile_body(body); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + +static void +c_let(cl_object args) { + c_let_leta(OP_PBIND, args); +} + +static void +c_leta(cl_object args) { + c_let_leta(OP_BIND, args); +} + +/* + MACROLET + + The current lexical environment is saved. A new one is prepared with + the definitions of these macros, and this environment is used to + compile the body. + */ +static void +c_macrolet(cl_object args) +{ + cl_object def_list, def, name; + int nfun = 0; + cl_object lex_old = lex_env; + lex_copy(); + + /* Pop the list of definitions */ + for (def_list = pop(&args); !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object arglist = pop(&definition); + cl_object macro, function; + macro = funcall(4, siSexpand_defmacro, name, arglist, + definition); + function = make_lambda(name, CDR(macro)); + lex_macro_bind(name, function); + } + compile_body(args); + lex_env = lex_old; +} + + +static void +c_multiple_value_bind(cl_object args) +{ + cl_object vars, value, body, specials; + cl_index save_pc, n; + cl_object lex_old = lex_env; + lex_copy(); + + vars = pop(&args); + value = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + compile_form(value, FALSE); + n = length(vars); + if (n == 0) { + compile_body(body); + } else { + asm_op(OP_PUSHENV); + asm_op2(OP_MBIND, n); + for (vars=reverse(vars); n; n--){ + cl_object var = pop(&vars); + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + if (special_variablep(var, specials)) { + asm1(MAKE_FIXNUM(1)); + c_register_var(var, TRUE); + } else + c_register_var(var, FALSE); + asm1(var); + } + compile_body(body); + asm_op(OP_EXIT); + } + lex_env = lex_old; +} + + +static void +c_multiple_value_call(cl_object args) { + cl_object name; + + name = pop(&args); + if (endp(args)) { + /* If no arguments, just use ordinary call */ + c_call(list(1, name), FALSE); + return; + } + asm_op(OP_MCALL); + do { + compile_form(pop(&args), FALSE); + asm_op(OP_PUSHVALUES); + } while (!endp(args)); + compile_form(name, FALSE); + asm_op(OP_EXIT); +} + + +static void +c_multiple_value_prog1(cl_object args) { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + asm_op(OP_MPROG1); + compile_body(args); + asm_op(OP_EXIT); + } +} + + +static void +c_multiple_value_setq(cl_object args) { + cl_object orig_vars; + cl_object vars = Cnil; + cl_object temp_vars = Cnil; + cl_object late_assignment = Cnil; + cl_index nvars = 0; + + /* Look for symbol macros, building the list of variables + and the list of late assignments. */ + for (orig_vars = reverse(pop(&args)); !endp(orig_vars); ) { + cl_object aux, v = pop(&orig_vars); + if (!SYMBOLP(v)) + FEillegal_variable_name(v); + v = macro_expand1(v, lex_env); + if (!SYMBOLP(v)) { + aux = v; + v = Lgensym(0); + temp_vars = CONS(v, temp_vars); + late_assignment = CONS(list(3, Ssetf, aux, v), + late_assignment); + } + vars = CONS(v, vars); + nvars++; + } + + if (!Null(temp_vars)) { + asm_op(OP_PUSHENV); + do { + compile_form(Cnil, FALSE); + c_bind(CAR(temp_vars), Cnil); + temp_vars = CDR(temp_vars); + } while (!Null(temp_vars)); + } + + /* Compile values */ + compile_form(pop(&args), FALSE); + if (args != Cnil) + FEprogram_error("MULTIPLE-VALUE-SETQ: Too many arguments.", 0); + if (nvars == 0) + /* No variables */ + return; + + /* Compile variables */ + asm_op2(OP_MSETQ, nvars); + vars = reverse(vars); + while (nvars--) { + cl_object ndx, var = pop(&vars); + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm1(var); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEassignment_to_constant(var); + else { + asm1(MAKE_FIXNUM(1)); + asm1(var); + } + } + + /* Assign to symbol-macros */ + if (!Null(late_assignment)) { + compile_body(late_assignment); + asm_op(OP_EXIT); + } +} + + +/* + The OP_NTHVAL operator moves a value from VALUES(ndx) to + VALUES(0). The index NDX is taken from the stack. + + OP_NTHVAL +*/ +static void +c_nth_value(cl_object args) { + compile_form(pop(&args), TRUE); /* INDEX */ + compile_form(pop(&args), FALSE); /* VALUES */ + if (args != Cnil) + FEprogram_error("NTH-VALUE: Too many arguments.",0); + asm_op(OP_NTHVAL); +} + + +static void +c_or(cl_object args) { + if (Null(args)) { + asm1(Cnil); + return; + } else if (ATOM(args)) { + FEill_formed_input(); + } else { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JT); + c_or(args); + asm_complete(OP_JT, label); + } + } +} + + +/* + The OP_PROGV operator exectures a set of statements in a lexical + environment that has been extended with special variables. The + list of special variables is taken from the top of the stack, + while the list of values is in VALUES(0). + + ... ; list of variables + OP_PUSH + ... ; list of values + OP_PROGV + ... ; body of progv + OP_EXIT +*/ +static void +c_progv(cl_object args) { + cl_object vars = pop(&args); + cl_object values = pop(&args); + + /* The list of variables is in the stack */ + compile_form(vars, TRUE); + + /* The list of values is in VALUES(0) */ + compile_form(values, FALSE); + + /* The body is interpreted within an extended lexical + environment. However, as all the new variables are + special, the compiler need not take care of them + */ + asm_op(OP_PROGV); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + There are four assignment operators. They are + + 1) Assign VALUES(0) to the lexical variable which occupies the + N-th position + [OP_SETQ + n] + + 2) Assign VALUES(0) to the special variable NAME + OP_SETQS + name + + 3) Pop a value from the stack and assign it to the lexical + variable in the N-th position. + [OP_PSETQ + n] + + 4) Pop a value from the stack and assign it to the special + variable denoted by NAME + OP_PSETQS + name +*/ +static void +c_psetq(cl_object old_args) { + cl_object args = Cnil, vars = Cnil; + bool use_psetf = FALSE; + cl_index nvars = 0; + + /* We have to make sure that non of the variables which + are to be assigned is actually a symbol macro. If that + is the case, we invoke (PSETF ...) to handle the + macro expansions. + */ + while (!endp(old_args)) { + cl_object var = pop(&old_args); + cl_object value = pop(&old_args); + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + var = macro_expand1(var, lex_env); + if (!SYMBOLP(var)) + use_psetf = TRUE; + args = CONS(var, CONS(value, args)); + nvars++; + } + if (use_psetf) { + compile_form(CONS(Spsetf, args), FALSE); + return; + } + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + vars = CONS(var, vars); + compile_form(value, TRUE); + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); +} + + +/* + The OP_RETFROM operator returns from a block using the objects + in VALUES() as output values. + + ... ; output form + OP_RETFROM + tag ; object which names the block +*/ +static void +c_return(cl_object stmt) { + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + asm1(Cnil); + if (stmt != Cnil) + FEprogram_error("RETURN: Too many arguments.", 0); +} + + +static void +c_return_from(cl_object stmt) { + cl_object name = pop(&stmt); + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + if (!SYMBOLP(name)) + FEprogram_error("RETURN-FROM: Not a valid tag ~S.", 1, name); + asm1(name); + if (stmt != Cnil) + FEprogram_error("RETURN-FROM: Too many arguments.", 0); +} + + +static void +c_setq(cl_object args) { + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + if (!SYMBOLP(var)) + FEillegal_variable_name(var); + var = macro_expand1(var, lex_env); + if (SYMBOLP(var)) { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } else { + compile_form(list(3, Ssetf, var, value), FALSE); + } + } +} + + +static void +c_symbol_macrolet(cl_object args) +{ + cl_object def_list, def, name, specials, body; + cl_object lex_old = lex_env; + int nfun = 0; + + /* Set a new lexical environment where we will bind + our macrology */ + lex_copy(); + + def_list = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + /* Scan the list of definitions */ + for (; !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object expansion = pop(&definition); + cl_object arglist = list(2, Lgensym(0), Lgensym(0)); + cl_object function; + if (special_variablep(name, specials)) + FEprogram_error("SYMBOL-MACROLET: Symbol ~A cannot be \ +declared special and appear in a symbol-macrolet.", 1, name); + definition = list(2, arglist, list(2, Squote, expansion)); + function = make_lambda(name, definition); + lex_symbol_macro_bind(name, function); + } + compile_body(body); + lex_env = lex_old; +} + +static void +c_tagbody(cl_object args) +{ + cl_fixnum tag_base; + cl_object label, body; + enum type item_type; + int nt; + + /* count the tags */ + for (nt = 0, body = args; !endp(body); body = CDR(body)) { + label = CAR(body); + item_type = type_of(CAR(body)); + if (item_type == t_symbol || item_type == t_fixnum || + item_type == t_bignum) { + nt += 1; + } + } + if (nt == 0) { + compile_body(args); + compile_form(Cnil, FALSE); + return; + } + asm_op2(OP_TAGBODY, nt); + tag_base = current_pc(); + set_pc(tag_base + 2 * nt); + + for (body = args; !endp(body); body = CDR(body)) { + label = CAR(body); + item_type = type_of(label); + if (item_type == t_symbol || item_type == t_fixnum || + item_type == t_bignum) { + asm_at(tag_base, label); + tag_base++; + asm_at(tag_base, MAKE_FIXNUM(current_pc()-tag_base)); + tag_base++; + } else { + compile_form(label, FALSE); + } + } + asm_op(OP_EXIT); +} + + +/* + The OP_THROW jumps to an enclosing OP_CATCH whose tag + matches the one of the throw. The tag is taken from the + stack, while the output values are left in VALUES(). +*/ +static void +c_throw(cl_object stmt) { + /* FIXME! Do we apply the right protocol here? */ + cl_object tag = pop(&stmt); + cl_object form = pop(&stmt); + if (stmt != Cnil) + FEprogram_error("THROW: Too many arguments.",0); + compile_form(tag, TRUE); + compile_form(form, FALSE); + asm_op(OP_THROW); +} + + +static void +c_unless(cl_object form) { + cl_fixnum label_true, label_false; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JT); + + /* Compile body */ + compile_body(form); + label_false = asm_jmp(OP_JMP); + asm_complete(OP_JT, label_true); + + /* When test failed, output NIL */ + asm1(Cnil); + asm_complete(OP_JMP, label_false); +} + + +static void +c_unwind_protect(cl_object args) { + cl_index label = asm_jmp(OP_UNWIND); + + /* Compile form to be protected */ + compile_form(pop(&args), FALSE); + asm_op(OP_EXIT); + + /* Compile exit clause */ + asm_complete(OP_UNWIND, label); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + The OP_VALUES moves N values from the stack to VALUES(). + + [OP_VALUES + n] +*/ +static void +c_values(cl_object args) { + int n = 0; + + while (!endp(args)) { + compile_form(pop_maybe_nil(&args), TRUE); + n++; + } + asm_op2(OP_VALUES, n); +} + + +static void +c_when(cl_object form) { + cl_fixnum label; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label = asm_jmp(OP_JNIL); + + /* Compile body */ + compile_body(form); + asm_complete(OP_JNIL, label); +} + + +static void +compile_form(cl_object stmt, bool push) { + compiler_record *l; + cl_object function; + cl_object macro; + + /* FIXME! We should protect this region with error handling */ + BEGIN: + /* + * First try with variable references and quoted constants + */ + if (ATOM(stmt)) { + if (SYMBOLP(stmt)) { + cl_object stmt1 = macro_expand1(stmt, lex_env); + if (stmt1 != stmt) { + stmt = stmt1; + goto BEGIN; + } + if (push) asm_op(OP_PUSHV); + asm1(stmt); + goto OUTPUT; + } + QUOTED: + if (push) + asm_op(OP_PUSHQ); + else if (FIXNUMP(stmt) || SYMBOLP(stmt)) + asm_op(OP_QUOTE); + asm1(stmt); + goto OUTPUT; + } + LIST: + /* + * Next try with special forms. + */ + function = CAR(stmt); + if (!SYMBOLP(function)) + goto ORDINARY_CALL; + if (function == Squote) { + stmt = CDR(stmt); + if (CDR(stmt) != Cnil) + FEprogram_error("QUOTE: Too many arguments.",0); + stmt = CAR(stmt); + goto QUOTED; + } + for (l = database; l->symbol != OBJNULL; l++) + if (l->symbol == function) { + (*(l->compiler))(CDR(stmt)); + if (push) asm_op(OP_PUSH); + goto OUTPUT; + } + /* + * Next try to macroexpand + */ + { + cl_object new_stmt = macro_expand1(stmt, lex_env); + if (new_stmt != stmt){ + stmt = new_stmt; + goto BEGIN; + } + } + if (function->symbol.isform) + FEprogram_error("BYTECOMPILE-FORM: Found no macroexpander \ +for special form ~S.", 1, function); + ORDINARY_CALL: + /* + * Finally resort to ordinary function calls. + */ + c_call(stmt, push); + OUTPUT: +} + + +static void +compile_body(cl_object body) { + if (endp(body)) + asm_op(OP_NOP); + else do { + compile_form(CAR(body), FALSE); + body = CDR(body); + } while (!endp(body)); +} + +/* ----------------------------- PUBLIC INTERFACE ---------------------------- */ + +/* ------------------------------------------------------------ + LAMBDA OBJECTS: An interpreted function is a vector made of + the following components + + #(LAMBDA + {block-name | NIL} + {variable-env | NIL} + {function-env | NIL} + {block-env | NIL} + (list of variables declared special) + Nreq {var}* ; required arguments + Nopt {var value flag}* ; optional arguments + {rest-var NIL} ; rest variable + {T | NIL} ; allow other keys? + Nkey {key var value flag}* ; keyword arguments + Naux {var init} ; auxiliary variables + documentation-string + list-of-declarations + {form}* ; body) + + ------------------------------------------------------------ */ + +#define push(v,l) l = CONS(v, l) +#define push_var(v, list) \ + check_symbol(v); \ + if (v->symbol.stype == stp_constant) \ + FEillegal_variable_name(v); \ + push(v, list); + +/* + Handles special declarations, removes declarations from body + */ +@(defun si::process_declarations (body &optional doc) + cl_object documentation = Cnil, declarations = Cnil, form, specials = Cnil; + cl_object decls, vars, v; +@ + /* BEGIN: SEARCH DECLARE */ + for (; !endp(body); body = CDR(body)) { + form = CAR(body); + + if (!Null(doc) && type_of(form) == t_string) { + if (documentation == Cnil) + documentation = form; + else + break; + continue; + } + + if (ATOM(form) || (CAR(form) != Sdeclare)) + break; + + for (decls = CDR(form); !endp(decls); decls = CDR(decls)) { + cl_object sentence = CAR(decls); + if (ATOM(sentence)) + FEill_formed_input(); + push(sentence, declarations); + if (CAR(sentence) == Sspecial) + for (vars = CDR(sentence); !endp(vars); vars = CDR(vars)) { + v = CAR(vars); + check_symbol(v); + push(v,specials); + } + } + } + /* END: SEARCH DECLARE */ + + @(return declarations body documentation specials) +@) + +@(defun si::process_lambda_list (lambda) + cl_object documentation, declarations, specials; + cl_object lambda_list, body, form; + cl_object x, v, key, init, spp; + cl_object reqs = Cnil, opts = Cnil, keys = Cnil, rest = Cnil, auxs = Cnil; + int nreq = 0, nopt = 0, nkey = 0, naux = 0; + cl_object allow_other_keys = Cnil; +@ + bds_check; + if (ATOM(lambda)) + FEprogram_error("LAMBDA: No lambda list.", 0); + lambda_list = CAR(lambda); + + declarations = siLprocess_declarations(2, CDR(lambda), Ct); + body = VALUES(1); + documentation = VALUES(2); + specials = VALUES(3); + +REQUIRED: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAoptional) + goto OPTIONAL; + if (v == SArest) + goto REST; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + nreq++; + push_var(v, reqs); + } +OPTIONAL: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + spp = Cnil; + init = Cnil; + if (ATOM(x)) { + if (x == SAoptional || x == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (x == SArest) + goto REST; + if (x == SAkey) + goto KEYWORD; + if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + nopt++; + push_var(v, opts); + push(init, opts); + if (spp != Cnil) { + push_var(spp, opts); + } else { + push(Cnil, opts); + } + } + +REST: + if (endp(lambda_list)) + goto ILLEGAL_LAMBDA; + v = CAR(lambda_list); + push_var(v, rest); + + lambda_list = CDR(lambda_list); + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAoptional || v == SArest || v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + goto ILLEGAL_LAMBDA; + +KEYWORD: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + init = Cnil; + spp = Cnil; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAallow_other_keys) { + if (!Null(allow_other_keys)) + goto ILLEGAL_LAMBDA; + allow_other_keys = Ct; + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (key != SAaux) + goto ILLEGAL_LAMBDA; + goto AUX; + } else if (x == SAoptional || x == SArest || x == SAkey) + goto ILLEGAL_LAMBDA; + else if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + if (CONSP(v)) { + key = CAR(v); + if (endp(CDR(v)) || !endp(CDDR(v))) + goto ILLEGAL_LAMBDA; + v = CADR(v); + check_symbol(v); + check_symbol(key); + } else { + check_symbol(v); + key = intern(v->symbol.name, keyword_package); + } + nkey++; + push(key, keys); + push_var(v, keys); + push(init, keys); + if (Null(spp)) { + push(Cnil, keys); + } else { + push_var(spp, keys); + } + } + +AUX: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAoptional || x == SArest || + x == SAkey || x == SAallow_other_keys || + x == SAaux) + goto ILLEGAL_LAMBDA; + v = x; + init = Cnil; + } else if (endp(CDDR(x))) { + v = CAR(x); + init = CADR(x); + } else + goto ILLEGAL_LAMBDA; + naux++; + push_var(v, auxs); + push(init, auxs); + } + +OUTPUT: + @(return CONS(MAKE_FIXNUM(nreq), nreverse(reqs)) + CONS(MAKE_FIXNUM(nopt), nreverse(opts)) + nreverse(rest) + allow_other_keys + CONS(MAKE_FIXNUM(nkey), nreverse(keys)) + nreverse(auxs) + documentation + specials + declarations + body) + +ILLEGAL_LAMBDA: + FEprogram_error("LAMBDA: Illegal lambda list ~S.", 0); +@) + +static void +c_default(cl_index deflt_pc) { + cl_object deflt = asm_ref(deflt_pc); + enum cl_type t = type_of(deflt); + if ((t == t_symbol) && (deflt->symbol.stype == stp_constant)) + /* FIXME! Shouldn't this happen only in unsafe mode */ + asm_at(deflt_pc, SYM_VAL(deflt)); + else if ((t == t_symbol) || (t == t_cons) || (t == t_fixnum)) { + cl_index pc = current_pc(); + asm_at(deflt_pc, MAKE_FIXNUM(pc-deflt_pc)); + compile_form(deflt, FALSE); + asm_op(OP_EXIT); + } +} + +static void +c_register_var2(register cl_object var, register cl_object *specials) +{ + if (Null(var)) + return; + if (member_eq(var, *specials)) + c_register_var(var, TRUE); + else if (var->symbol.stype == stp_special) { + *specials = CONS(var, *specials); + c_register_var(var, TRUE); + } else if (var->symbol.stype == stp_constant) + FEassignment_to_constant(var); + else + c_register_var(var, FALSE); +} + +cl_object +make_lambda(cl_object name, cl_object lambda) { + cl_object reqs, opts, rest, keys, auxs, allow_other_keys; + cl_object specials, doc, decl, body, l; + cl_index specials_pc, opts_pc, keys_pc, label; + int nopts, nkeys; + cl_index handle; + cl_object lex_old = lex_env; + + lex_copy(); + + reqs = siLprocess_lambda_list(1,lambda); + opts = VALUES(1); + rest = VALUES(2); + allow_other_keys = VALUES(3); + keys = VALUES(4); + auxs = VALUES(5); + doc = VALUES(6); + specials = VALUES(7); + decl = VALUES(8); + body = VALUES(9); + + handle = asm_begin(); + + asm1(name); /* Name of the function */ + specials_pc = current_pc(); /* Which variables are declared special */ + asm1(specials); + + asm_list(reqs); /* Special arguments */ + reqs = CDR(reqs); + while (!endp(reqs)) { + cl_object v = pop(&reqs); + c_register_var2(v, &specials); + } + + opts_pc = current_pc()+1; /* Optional arguments */ + nopts = fix(CAR(opts)); + asm_list(opts); + + asm_list(rest); /* Name of &rest argument */ + + asm1(allow_other_keys); /* Value of &allow-other-keys */ + + keys_pc = current_pc()+1; /* Keyword arguments */ + nkeys = fix(CAR(keys)); + asm_list(keys); + asmn(2, doc, decl); + + label = asm_jmp(OP_JMP); + + while (nopts--) { + c_default(opts_pc+1); + c_register_var2(asm_ref(opts_pc), &specials); + c_register_var2(asm_ref(opts_pc+2), &specials); + opts_pc+=3; + } + c_register_var2(car(rest), &specials); + while (nkeys--) { + c_default(keys_pc+2); + c_register_var2(asm_ref(keys_pc+1), &specials); + c_register_var2(asm_ref(keys_pc+3), &specials); + keys_pc+=4; + } + + if ((current_pc() - label) == 1) + set_pc(label); + else + asm_complete(OP_JMP, label); + while (!endp(auxs)) { /* Local bindings */ + cl_object var = pop(&auxs); + cl_object value = pop(&auxs); + compile_form(value, FALSE); + c_bind(var, specials); + } + asm_at(specials_pc, specials); + compile_body(body); + asm_op(OP_HALT); + + lex_env = lex_old; + + return asm_end(handle); +} + +static cl_object +alloc_bytecodes() +{ + cl_object vector = alloc_simple_vector(128, aet_object); + array_allocself(vector); + vector->vector.hasfillp = TRUE; + vector->vector.fillp = 0; + return vector; +} + +@(defun si::make_lambda (name rest) + cl_object lambda, old_bytecodes = bytecodes; + cl_object lex_old = lex_env; +@ + lex_new(); + if (frs_push(FRS_PROTECT, Cnil)) { + lex_env = lex_old; + bytecodes = old_bytecodes; + frs_pop(); + unwind(nlj_fr, nlj_tag); + } + bytecodes = alloc_bytecodes(); + lambda = make_lambda(name,rest); + frs_pop(); + bytecodes = old_bytecodes; + lex_env = lex_old; + @(return lambda) +@) + +cl_object +eval(cl_object form, cl_object *new_bytecodes) +{ + cl_object old_bytecodes = bytecodes; + cl_index handle; + bool unwinding; + + if (new_bytecodes == NULL) + bytecodes = alloc_bytecodes(); + else if (*new_bytecodes != Cnil) { + bytecodes = *new_bytecodes; + } else { + bytecodes = *new_bytecodes = alloc_bytecodes(); + } + if (frs_push(FRS_PROTECT, Cnil)) { + bytecodes = old_bytecodes; + frs_pop(); + unwind(nlj_fr, nlj_tag); + } + handle = asm_begin(); + compile_form(form, FALSE); + asm_op(OP_EXIT); + asm_op(OP_HALT); +/* Lprint(1,bytecodes); */ + VALUES(0) = Cnil; + NValues = 0; + interpret(&bytecodes->vector.self.t[handle]); + asm_clear(handle); + frs_pop(); + bytecodes = old_bytecodes; + return VALUES(0); +} + +void +init_compiler(void) +{ + compiler_record *l; + + register_root(&bytecodes); + + for (l = database; l->name[0] != 0; l++) + l->symbol = _intern(l->name, lisp_package); +} diff --git a/src/c/disassembler.d b/src/c/disassembler.d new file mode 100644 index 000000000..4ee47ddaa --- /dev/null +++ b/src/c/disassembler.d @@ -0,0 +1,513 @@ +/* + disassembler.c -- Byte compiler and function evaluator +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +#define next_code(v) (*(v++)) + +static cl_object *disassemble(cl_object *vector); + +static cl_object *base = NULL; + +static cl_object * +disassemble_vars(const char *message, cl_object *vector, cl_index step) { + cl_index n = fix(next_code(vector)); + + if (n) { + Lterpri(0); + printf(message); + for (; n; n--, vector+=step) { + Lprin1(1,vector[0]); + if (n > 1) printf(", "); + } + } + return vector; +} + +static void +disassemble_lambda(cl_object *vector) { + cl_object specials; + cl_index n; + + Lterpri(0); + /* Name of LAMBDA */ + printf("Name:\t\t"); + Lprin1(1, next_code(vector)); + + /* Variables that have been declared special */ + specials = next_code(vector); + + /* Print required arguments */ + vector = disassemble_vars("Required:\t", vector, 1); + + /* Print optional arguments */ + vector = disassemble_vars("Optionals:\t", vector, 3); + + /* Print rest argument */ + if (vector[0] != Cnil) { + Lterpri(0); + printf("Rest:\t\t%s"); + Lprin1(1, vector[0]); + } + vector++; + + /* Print keyword arguments */ + if (vector[0] != Cnil) { + Lterpri(0); + printf("Other keys:\t"); + Lprin1(1, vector[0]); + } + vector++; + vector = disassemble_vars("Keywords:\t", vector, 4); + + /* Print aux arguments */ + Lterpri(0); + printf("\nDocumentation:\t"); + Lprin1(1, next_code(vector)); + printf("\nDeclarations:\t"); + Lprin1(1, next_code(vector)); + + base = vector; + while (vector[0] != MAKE_FIXNUM(OP_HALT)) + vector = disassemble(vector); +} + +/* -------------------- DISASSEMBLER AIDS -------------------- */ + +static inline cl_fixnum +get_oparg(cl_object o) { + return GET_OPARG(o); +} + +static inline cl_fixnum +packed_label(cl_object *v) { + return v + get_oparg(v[0]) - base; +} + +static inline cl_fixnum +simple_label(cl_object *v) { + return v + fix(v[0]) - base; +} + +static cl_object +search_symbol(register cl_object s) { + return s; +} + +/* -------------------- DISASSEMBLER CORE -------------------- */ + +static cl_object * +disassemble_block(cl_object *vector) { + cl_object lex_old = lex_env; + cl_fixnum exit = packed_label(vector-1); + + printf("BLOCK\t"); + Lprin1(1, next_code(vector)); + printf(",%d", exit); + vector = disassemble(vector); + printf("\t\t\t; block"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_catch(cl_object *vector) { + printf("CATCH\t%d", packed_label(vector - 1)); + vector = disassemble(vector); + printf("\t\t\t; catch"); + return vector; +} + +static cl_object * +disassemble_do(cl_object *vector) { + cl_fixnum exit; + cl_object lex_old = lex_env; + lex_copy(); + + exit = packed_label(vector-1); + printf("DO\t%d", exit); + vector = disassemble(vector); + printf("\t\t\t; do"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_dolist(cl_object *vector) { + cl_fixnum exit; + cl_object lex_old = lex_env; + + lex_copy(); + exit = packed_label(vector-1); + printf("DOLIST\t%d", exit); + vector = disassemble(vector); + printf("\t\t\t; dolist binding"); + vector = disassemble(vector); + printf("\t\t\t; dolist body"); + vector = disassemble(vector); + printf("\t\t\t; dolist"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_dotimes(cl_object *vector) { + cl_fixnum exit; + cl_object lex_old = lex_env; + + lex_copy(); + exit = packed_label(vector-1); + printf("DOTIMES\t%d", exit); + vector = disassemble(vector); + printf("\t\t\t; dotimes times"); + vector = disassemble(vector); + printf("\t\t\t; dotimes body"); + vector = disassemble(vector); + printf("\t\t\t; dotimes"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_flet(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index nfun = get_oparg(vector[-1]); + + printf("FLET"); + lex_copy(); + while (nfun--) { + cl_object fun = next_code(vector); + Lterpri(0); + printf("\tFLET\t"); + Lprin1(1, fun->bytecodes.data[0]); + } + vector = disassemble(vector); + printf("\t\t\t; flet"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_labels(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index nfun = get_oparg(vector[-1]); + + printf("LABELS"); + lex_copy(); + while (nfun--) { + cl_object fun = next_code(vector); + Lterpri(0); + printf("\tLABELS\t"); + Lprin1(1, fun->bytecodes.data[0]); + } + vector = disassemble(vector); + printf("\t\t\t; labels"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_mbind(cl_object *vector) +{ + int i = get_oparg(vector[-1]); + bool newline = FALSE; + while (i--) { + cl_object var = next_code(vector); + if (newline) { + Lterpri(0); + printf("\t"); + } else + newline = TRUE; + if (var == MAKE_FIXNUM(1)) { + printf("MBINDS\t"); + var = next_code(vector); + } else { + printf("MBIND\t"); + } + Lprin1(1, var); + printf(", VALUES(%d)", i); + } + return vector; +} + +static cl_object * +disassemble_mprog1(cl_object *vector) { + printf("MPROG1"); + vector = disassemble(vector); + printf("\t\t\t; mprog1"); + return vector; +} + + +static cl_object * +disassemble_msetq(cl_object *vector) +{ + int i = get_oparg(vector[-1]); + bool newline = FALSE; + while (i--) { + cl_object var = next_code(vector); + if (newline) { + Lterpri(0); + printf("\t"); + } else + newline = TRUE; + if (var == MAKE_FIXNUM(1)) { + printf("MSETQS\t"); + var = next_code(vector); + } else { + printf("MSETQ\t"); + } + Lprin1(1, var); + printf(", VALUES(%d)", i); + } + return vector; +} + + +static cl_object * +disassemble_progv(cl_object *vector) { + printf("PROGV"); + vector = disassemble(vector); + printf("\t\t\t; progv"); + return vector; +} + +static cl_object * +disassemble_pushenv(cl_object *vector) { + cl_object lex_old = lex_env; + lex_copy(); + + printf("PUSHENV"); + vector = disassemble(vector); + printf("\t\t\t; pushenv"); + + lex_env = lex_old; + return vector; +} + +/* OP_TAGBODY n-tags + tag1 addr1 + tag2 addr2 + ... ... + tagn addrn + {form}* + OP_EXIT +*/ + +static cl_object * +disassemble_tagbody(cl_object *vector) { + cl_index ntags = get_oparg(vector[-1]); + cl_object lex_old = lex_env; + lex_copy(); + + printf("TAGBODY"); + while (ntags--) { + Lterpri(0); + printf("\tTAG\t'"); + Lprin1(1, vector[0]); + printf(" @@ %d", simple_label(vector+1)); + vector+=2; + } + vector = disassemble(vector); + printf("\t\t\t; tagbody"); + + lex_env = lex_old; + return vector; +} + +static cl_object * +disassemble_unwind_protect(cl_object *vector) { + cl_fixnum exit = packed_label(vector-1); + + printf("PROTECT\t%d", exit); + vector = disassemble(vector); + vector = disassemble(vector); + printf("\t\t\t; protect"); + + return vector; +} + +static cl_object * +disassemble(cl_object *vector) { + const char *string; + enum cl_type t; + cl_object s; + cl_fixnum n; + + BEGIN: + Lterpri(0); + printf("%4d\t", vector - base); + s = next_code(vector); + t = type_of(s); + if (t == t_symbol) { + Lprin1(1, search_symbol(s)); + goto BEGIN; + } + if (t != t_fixnum) { + Lprin1(1, s); + goto BEGIN; + } + switch (GET_OP(s)) { + case OP_PUSHQ: printf("PUSH\t'"); + Lprin1(1, next_code(vector)); + break; + case OP_PUSH: string = "PUSH\tVALUES(0)"; + goto NOARG; + case OP_PUSHV: string = "PUSHV"; + s = search_symbol(next_code(vector)); + goto ARG; + case OP_QUOTE: string = "QUOTE"; + s = next_code(vector); + goto ARG; + case OP_NOP: string = "NOP"; + goto NOARG; + case OP_BLOCK: vector = disassemble_block(vector); + break; + case OP_PUSHVALUES: string = "PUSH\tVALUES"; + goto NOARG; + case OP_MCALL: string = "MCALL"; + goto NOARG; + case OP_CALL: string = "CALL"; + n = get_oparg(s); + s = next_code(vector); + goto OPARG_ARG; + case OP_PCALL: string = "PCALL"; + n = get_oparg(s); + s = next_code(vector); + goto OPARG_ARG; + case OP_FCALL: string = "FCALL"; + n = get_oparg(s); + goto OPARG; + case OP_PFCALL: string = "PFCALL"; + n = get_oparg(s); + goto OPARG; + case OP_CATCH: vector = disassemble_catch(vector); + break; + case OP_EXIT: printf("EXIT"); + return vector; + case OP_HALT: printf("HALT"); + return vector-1; + case OP_FLET: vector = disassemble_flet(vector); + break; + case OP_LABELS: vector = disassemble_labels(vector); + break; + case OP_FUNCTION: string = "SYMFUNC"; + s = next_code(vector); + goto ARG; + case OP_CLOSE: string = "CLOSE"; + s = next_code(vector); + goto ARG; + case OP_GO: string = "GO"; + s = next_code(vector); + goto ARG; + case OP_RETURN: string = "RETFROM"; + s = next_code(vector); + goto ARG; + case OP_THROW: string = "THROW"; + goto NOARG; + case OP_JMP: string = "JMP"; + n = packed_label(vector-1); + goto OPARG; + case OP_JNIL: string = "JNIL"; + n = packed_label(vector-1); + goto OPARG; + case OP_JT: string = "JT"; + n = packed_label(vector-1); + goto OPARG; + case OP_JEQ: string = "JEQ"; + s = next_code(vector); + n = packed_label(vector-2); + goto OPARG_ARG; + case OP_JNEQ: string = "JNEQ"; + s = next_code(vector); + n = packed_label(vector-2); + goto OPARG_ARG; + case OP_BIND: string = "BIND"; goto SETQ; + case OP_BINDS: string = "BINDS"; goto SETQS; + case OP_PBIND: string = "PBIND"; goto SETQ; + case OP_PBINDS: string = "PBINDS"; goto SETQS; + case OP_PSETQ: string = "PSETQ"; goto SETQ; + case OP_PSETQS: string = "PSETQS"; goto SETQS; + case OP_SETQ: string = "SETQ"; + SETQ: s = next_code(vector); + goto ARG; + case OP_SETQS: string = "SETQS"; + SETQS: s = next_code(vector); + goto ARG; + case OP_MSETQ: vector = disassemble_msetq(vector); + break; + case OP_MBIND: vector = disassemble_mbind(vector); + break; + case OP_MPROG1: vector = disassemble_mprog1(vector); + break; + case OP_PROGV: vector = disassemble_progv(vector); + break; + case OP_PUSHENV: vector = disassemble_pushenv(vector); + break; + case OP_VALUES: string = "VALUES"; + n = get_oparg(s); + goto OPARG; + case OP_NTHVAL: string = "NTHVAL"; + goto NOARG; + case OP_DOLIST: vector = disassemble_dolist(vector); + break; + case OP_DOTIMES: vector = disassemble_dotimes(vector); + break; + case OP_DO: vector = disassemble_do(vector); + break; + case OP_TAGBODY: vector = disassemble_tagbody(vector); + break; + case OP_UNWIND: vector = disassemble_unwind_protect(vector); + break; + default: + FEerror("Unknown code ~S", 1, MAKE_FIXNUM(*(vector-1))); + return; + NOARG: printf(string); + break; + ARG: printf("%s\t", string); + Lprin1(1, s); + break; + OPARG: printf("%s\t%d", string, n); + break; + OPARG_ARG: printf("%s\t%d,", string, n); + Lprin1(1, s); + break; + } + goto BEGIN; +} + +@(defun si::bc_disassemble (v) +@ + if (type_of(v) == t_bytecodes) + disassemble_lambda(v->bytecodes.data); + @(return v) +@) + +@(defun si::bc_split (b) + cl_object vector; +@ + if (type_of(b) != t_bytecodes) + @(return Cnil Cnil) + vector = alloc_simple_vector(b->bytecodes.size, aet_object); + vector->vector.self.t = b->bytecodes.data; + @(return b->bytecodes.lex vector) +@) diff --git a/src/c/dosdummy.d b/src/c/dosdummy.d new file mode 100644 index 000000000..bba9a6943 --- /dev/null +++ b/src/c/dosdummy.d @@ -0,0 +1,9 @@ +#define DUM(a) int a(int n) {} + +DUM(alarm) +DUM(getpid) +DUM(getuid) +DUM(popen) +DUM(pclose) +DUM(getpwuid) +DUM(getpwnam) diff --git a/src/c/dostimes.d b/src/c/dostimes.d new file mode 100644 index 000000000..062e8dc83 --- /dev/null +++ b/src/c/dostimes.d @@ -0,0 +1,18 @@ +#include +#include + +#ifdef __ZTC__ +#define HZ 100 +#endif + +times(struct tms *x) +{ int hz; + struct rusage ru; + getrusage(RUSAGE_SELF,&ru); + hz = ru.ru_utime.tv_sec * HZ + + (ru.ru_utime.tv_usec * HZ)/1000000; + x->tms_utime = hz; + x->tms_stime = hz; + return 0; +} + diff --git a/src/c/dpp.c b/src/c/dpp.c new file mode 100644 index 000000000..ff4022805 --- /dev/null +++ b/src/c/dpp.c @@ -0,0 +1,701 @@ +/* + dpp.c -- Defun preprocessor. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +/* + Usage: + dpp [in-file [out-file]] + + The file named in-file is preprocessed and the output will be + written to the file whose name is out-file. If in-file is "-" + program is read from standard input, while if out-file is "-" + C-program is written to standard output. + + + The function definition: + + @(defun name ({var}* + [&optional {var | (var [initform [svar]])}*] + [&rest var] + [&key {var | + ({var | (keyword var)} [initform [svar]])}* + [&allow_other_keys]] + [&aux {var | (var [initform])}*]) + + C-declaration + + @ + + C-body + + @) + + name can be either an identifier or a full C procedure header + enclosed in quotes ('). + + &optional may be abbreviated as &o. + &rest may be abbreviated as &r. + &key may be abbreviated as &k. + &allow_other_keys may be abbreviated as &aok. + &aux may be abbreviated as &a. + + Each variable becomes a C variable. + + Each supplied-p parameter becomes a boolean C variable. + + Initforms are C expressions. + It an expression contain non-alphanumeric characters, + it should be surrounded by backquotes (`). + + + Function return: + + @(return {form}*) + +*/ + +#include +#include +#include + +#define POOLSIZE 2048 +#define MAXREQ 16 +#define MAXOPT 16 +#define MAXKEY 16 +#define MAXAUX 16 +#define MAXRES 16 + +#define TRUE 1 +#define FALSE 0 + +typedef int bool; + +FILE *in, *out; + +char filename[BUFSIZ]; +int lineno; +int tab; +int tab_save; + +char pool[POOLSIZE]; +char *poolp; + +char *function; + +char *required[MAXREQ]; +int nreq; + +struct optional { + char *o_var; + char *o_init; + char *o_svar; +} optional[MAXOPT]; +int nopt; + +bool rest_flag; +char *rest_var; + +bool key_flag; +struct keyword { + char *k_key; + char *k_var; + char *k_init; + char *k_svar; +} keyword[MAXKEY]; +int nkey; +bool allow_other_keys_flag; + +struct aux { + char *a_var; + char *a_init; +} aux[MAXAUX]; +int naux; + +char *result[MAXRES]; +int nres; + +put_lineno(void) +{ + static int flag = 0; + if (flag) + fprintf(out, "#line %d\n", lineno); + else { + flag++; + fprintf(out, "#line %d \"%s\"\n", lineno, filename); + } +} + +error(char *s) +{ + printf("Error in line %d: %s.\n", lineno, s); + exit(1); +} + +error_symbol(char *s) +{ + printf("Error in line %d: illegal symbol %s.\n", lineno, s); + exit(1); +} + +readc(void) +{ + int c; + + c = getc(in); + if (feof(in)) { + if (function != NULL) + error("unexpected end of file"); + exit(0); + } + if (c == '\n') { + lineno++; + tab = 0; + } else if (c == '\t') + tab++; + return(c); +} + +nextc(void) +{ + int c; + + while (isspace(c = readc())) + ; + return(c); +} + +unreadc(int c) +{ + if (c == '\n') + --lineno; + else if (c == '\t') + --tab; + ungetc(c, in); +} + +put_tabs(int n) +{ + put_lineno(); + while (n--) + putc('\t', out); +} + +pushc(int c) +{ + if (poolp >= &pool[POOLSIZE]) + error("buffer pool overflow"); + *poolp++ = c; +} + +char * +read_token(void) +{ + int c; + int stop = 0; + int left_paren = 0; + char *p; + + p = poolp; + if ((c = nextc()) == '`') { + while ((c = readc()) != '`') + pushc(c); + } else { + do + if (c == '(') { + left_paren++; + pushc(c); + c = readc(); + } else if (c == ')') { + if (left_paren == 0) + stop = 1; + else { + left_paren--; + pushc(c); + c = readc(); + } + } else if (isspace(c) && left_paren == 0) { + stop = 1; + } else { + pushc(c); + c = readc(); + } + while (!stop); + unreadc(c); + } + pushc('\0'); + return(p); +} + +reset(void) +{ + int i; + + poolp = pool; + function = NULL; + nreq = 0; + for (i = 0; i < MAXREQ; i++) + required[i] = NULL; + nopt = 0; + for (i = 0; i < MAXOPT; i++) + optional[i].o_var + = optional[i].o_init + = optional[i].o_svar + = NULL; + rest_flag = FALSE; + rest_var = "ARGS"; + key_flag = FALSE; + nkey = 0; + for (i = 0; i < MAXKEY; i++) + keyword[i].k_key + = keyword[i].k_var + = keyword[i].k_init + = keyword[i].k_svar + = NULL; + allow_other_keys_flag = FALSE; + naux = 0; + for (i = 0; i < MAXAUX; i++) + aux[i].a_var + = aux[i].a_init + = NULL; +} + +get_function(void) +{ + function = read_token(); +} + +get_lambda_list(void) +{ + int c; + char *p; + + if ((c = nextc()) != '(') + error("( expected"); + for (;;) { + if ((c = nextc()) == ')') + return; + if (c == '&') { + p = read_token(); + goto OPTIONAL; + } + unreadc(c); + p = read_token(); + if (nreq >= MAXREQ) + error("too many required variables"); + required[nreq++] = p; + } + +OPTIONAL: + if (strcmp(p, "optional") != 0 && strcmp(p, "o") != 0) + goto REST; + for (;; nopt++) { + if ((c = nextc()) == ')') + return; + if (c == '&') { + p = read_token(); + goto REST; + } + if (nopt >= MAXOPT) + error("too many optional argument"); + if (c == '(') { + optional[nopt].o_var = read_token(); + if ((c = nextc()) == ')') + continue; + unreadc(c); + optional[nopt].o_init = read_token(); + if ((c = nextc()) == ')') + continue; + unreadc(c); + optional[nopt].o_svar = read_token(); + if (nextc() != ')') + error(") expected"); + } else { + unreadc(c); + optional[nopt].o_var = read_token(); + } + } + +REST: + if (strcmp(p, "rest") != 0 && strcmp(p, "r") != 0) + goto KEYWORD; + rest_flag = TRUE; + if ((c = nextc()) == ')' || c == '&') + error("&rest var missing"); + unreadc(c); + rest_var = read_token(); + if ((c = nextc()) == ')') + return; + if (c != '&') + error("& expected"); + p = read_token(); + goto KEYWORD; + +KEYWORD: + if (strcmp(p, "key") != 0 && strcmp(p, "k") != 0) + goto AUX; + key_flag = TRUE; + for (;; nkey++) { + if ((c = nextc()) == ')') + return; + if (c == '&') { + p = read_token(); + if (strcmp(p, "allow_other_keys") == 0 || + strcmp(p, "aok") == 0) { + allow_other_keys_flag = TRUE; + if ((c = nextc()) == ')') + return; + if (c != '&') + error("& expected"); + p = read_token(); + } + goto AUX; + } + if (nkey >= MAXKEY) + error("too many optional argument"); + if (c == '(') { + if ((c = nextc()) == '(') { + p = read_token(); + if (p[0] != ':' || p[1] == '\0') + error("keyword expected"); + keyword[nkey].k_key = p + 1; + keyword[nkey].k_var = read_token(); + if (nextc() != ')') + error(") expected"); + } else { + unreadc(c); + keyword[nkey].k_key + = keyword[nkey].k_var + = read_token(); + } + if ((c = nextc()) == ')') + continue; + unreadc(c); + keyword[nkey].k_init = read_token(); + if ((c = nextc()) == ')') + continue; + unreadc(c); + keyword[nkey].k_svar = read_token(); + if (nextc() != ')') + error(") expected"); + } else { + unreadc(c); + keyword[nkey].k_key + = keyword[nkey].k_var + = read_token(); + } + } + +AUX: + if (strcmp(p, "aux") != 0 && strcmp(p, "a") != 0) + error("illegal lambda-list keyword"); + for (;;) { + if ((c = nextc()) == ')') + return; + if (c == '&') + error("illegal lambda-list keyword"); + if (naux >= MAXAUX) + error("too many auxiliary variable"); + if (c == '(') { + aux[naux].a_var = read_token(); + if ((c = nextc()) == ')') + continue; + unreadc(c); + aux[naux].a_init = read_token(); + if (nextc() != ')') + error(") expected"); + } else { + unreadc(c); + aux[naux].a_var = read_token(); + } + naux++; + } +} + +get_return(void) +{ + int c; + + nres = 0; + for (;;) { + if ((c = nextc()) == ')') + return; + unreadc(c); + result[nres++] = read_token(); + } +} + +put_fhead(void) +{ + bool b = FALSE; char *q, *p = function; + int i; + put_lineno(); + fprintf(out, "cl_object\n"); + for (p = function; *p != '\0' && *p != ':' && *p != '('; p++); + if (*p != ':') + p = function; + else { + for(q = function; q < p; q++) + fputc(*q, out); + while (*p == ':') p++; + } + fputc('L',out); + while (!b && *p != '\0') { + fputc(*p, out); + b = (*p++ == '('); + } + if (b) { + /* + @(defun `assoc_or_rassoc(cl_object (*car_or_cdr)())` + (item a_list &key test test_not key) + must become: + Lassoc_or_rassoc(int narg, cl_object (*car_or_cdr)(), + cl_object item, cl_object a_list, ...) + */ + fprintf(out, "int narg, "); + while (*p != ')' || p[1] != '\0') + fputc(*p++, out); + } + else + fprintf(out, "(int narg", function); + + for (i = 0; i < nreq; i++) + fprintf(out, ", cl_object %s", required[i]); + if (nopt > 0 || rest_flag || key_flag) + fprintf(out, ", ..."); + fprintf(out, ")\n"); + if (b) { + while (*p++ != ')') ; + fprintf(out, "%s", p); /* declaration of extra first arg */ + } + fprintf(out, "{\n"); +} + +put_declaration(void) +{ + int i; + + for (i = 0; i < nopt; i++) { + put_lineno(); + fprintf(out, "\tcl_object %s;\n", optional[i].o_var); + } + for (i = 0; i < nopt; i++) + if (optional[i].o_svar != NULL) { + put_lineno(); + fprintf(out, "\tbool %s;\n", optional[i].o_svar); + } + if (nkey > 0) { + put_lineno(); + fprintf(out, "\tcl_object KEYS[%d];\n", nkey); + } + for (i = 0; i < nkey; i++) { + fprintf(out, "\tcl_object %s;\n", keyword[i].k_var); + if (keyword[i].k_svar != NULL) + fprintf(out, "\tbool %s;\n", keyword[i].k_svar); + } + for (i = 0; i < naux; i++) { + put_lineno(); + fprintf(out, "\tcl_object %s;\n", aux[i].a_var); + } + if (nopt == 0 && !rest_flag && !key_flag) { + put_lineno(); + fprintf(out, "\tcheck_arg(%d);\n", nreq); + } else { + if (key_flag) { + put_lineno(); + fprintf(out, "\tcl_object KEY_VARS[%d];\n", 2*nkey); + } + put_lineno(); + fprintf(out, "\tva_list %s;\n\tva_start(%s, %s);\n", rest_var, rest_var, + ((nreq > 0) ? required[nreq-1] : "narg")); + put_lineno(); + fprintf(out, "\tif (narg < %d) FEtoo_few_arguments(&narg);\n", nreq); + if (nopt > 0 && !rest_flag && !key_flag) { + put_lineno(); + fprintf(out, "\tif (narg > %d) FEtoo_many_arguments(&narg);\n", nreq + nopt); + } + for (i = 0; i < nopt; i++) { + put_lineno(); + fprintf(out, "\tif (narg > %d) {\n", nreq+i, optional[i].o_var); + put_lineno(); + fprintf(out, "\t\t%s = va_arg(%s, cl_object);\n", + optional[i].o_var, rest_var); + if (optional[i].o_svar) { + put_lineno(); + fprintf(out, "\t\t%s = TRUE;\n", optional[i].o_svar); + } + put_lineno(); + fprintf(out, "\t} else {\n"); + put_lineno(); + fprintf(out, "\t\t%s = %s;\n", + optional[i].o_var, + optional[i].o_init == NULL ? "Cnil" : optional[i].o_init); + if (optional[i].o_svar) { + put_lineno(); + fprintf(out, "\t\t%s = FALSE;\n", optional[i].o_svar); + } + put_lineno(); + fprintf(out, "\t}\n"); + } + if (key_flag) { + for (i = 0; i < nkey; i++) { + put_lineno(); + fprintf(out, "\tKEYS[%d]=K%s;\n", i, keyword[i].k_key); + } + put_lineno(); + fprintf(out, "\tparse_key(narg-%d, (cl_object*)ARGS, %d, KEYS, KEY_VARS, %s, %d);\n", + nreq+nopt, nkey, rest_flag ? rest_var : "OBJNULL", allow_other_keys_flag); + for (i = 0; i < nkey; i++) { + put_lineno(); + fprintf(out, "\tif (KEY_VARS[%d]==Cnil) {\n", nkey+i); + if (keyword[i].k_init != NULL) { + put_lineno(); + fprintf(out, "\t %s = %s;\n", keyword[i].k_var, keyword[i].k_init); + } else { + put_lineno(); + fprintf(out, "\t %s = Cnil;\n", keyword[i].k_var); + } + if (keyword[i].k_svar != NULL) { + put_lineno(); + fprintf(out, "\t %s = FALSE;\n", keyword[i].k_svar); + } + fprintf(out, "\t} else {\n"); + if (keyword[i].k_svar != NULL) { + put_lineno(); + fprintf(out, "\t %s = TRUE;\n", keyword[i].k_svar); + } + put_lineno(); + fprintf(out, "\t %s = KEY_VARS[%d];\n\t}\n", keyword[i].k_var, i); + } + } + } + for (i = 0; i < naux; i++) { + put_lineno(); + fprintf(out, "\t%s = %s;\n", aux[i].a_var, + aux[i].a_init == NULL ? "Cnil" : aux[i].a_init); + } +} + +put_return(void) +{ + int i, t; + + t = tab_save+1; + if (nres == 0) { + fprintf(out, "return0();"); + } else if (nres == 1) { + fprintf(out, "return1(%s);", result[0]); + } else { + fprintf(out, "{\n"); + put_tabs(t); + fprintf(out, "cl_object saved_value = %s;\n", result[0]); + for (i = 1; i < nres; i++) { + put_tabs(t); + fprintf(out, "VALUES(%d) = %s;\n", i, result[i]); + } + put_tabs(t); + fprintf(out, "NValues = %d;\n", nres); + put_tabs(t); + fprintf(out, "return saved_value;\n"); + put_tabs(tab_save); + fprintf(out, "}\n"); + } +} + +char +jump_to_at(void) +{ + char c; + GO_ON: + while ((c = readc()) != '@') + putc(c, out); + if ((c = readc()) == '@') { + putc(c, out); + goto GO_ON; + } + return c; +} + +main_loop(void) +{ + int c; + int in_defun=0; + char *p; + + lineno = 1; + + reset(); + put_lineno(); +LOOP: + c = jump_to_at(); + if (c == ')') { + if (!in_defun) + error("unmatched @) found"); + in_defun = 0; + putc('}',out); + reset(); + goto LOOP; + } + if (c != '(') + error("@( expected"); + p = read_token(); + if (strcmp(p, "defun") == 0) { + if (in_defun) + error("@) expected before new function definition"); + in_defun = 1; + get_function(); + get_lambda_list(); + put_fhead(); + put_lineno(); + c = jump_to_at(); + put_declaration(); + put_lineno(); + } else if (strcmp(p, "return") == 0) { + if (!in_defun) + error("@(return) found outside @(defun)"); + tab_save = tab; + get_return(); + put_return(); + } else + error_symbol(p); + goto LOOP; +} + +main(int argc, char **argv) +{ + char *p, *q; + char outfile[BUFSIZ]; + + if (argc < 2 || !strcmp(argv[1],"-")) { + in = stdin; + strcpy(filename, "-"); + } else { + in = fopen(argv[1],"r"); + strncpy(filename, argv[1], BUFSIZ); + } + if (argc < 3 || !strcmp(argv[2],"-")) { + out = stdout; + strncpy(outfile, "-", BUFSIZ); + } else { + out = fopen(argv[2],"w"); + strncpy(outfile, argv[2], BUFSIZ); + } + if (in == NULL) + error("can't open input file"); + if (out == NULL) + error("can't open output file"); + printf("dpp: %s -> %s\n", filename, outfile); + main_loop(); +} diff --git a/src/c/earith.d b/src/c/earith.d new file mode 100644 index 000000000..574f44907 --- /dev/null +++ b/src/c/earith.d @@ -0,0 +1,493 @@ +/* + earith.c -- Support for bignum arithmetic. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +/* + + EXTENDED_MUL and EXTENDED_DIV perform 32 bit multiplication and + division, respectively. + + EXTENDED_MUL(D,Q,R,HP,LP) + calculates D*Q+R and saves the result into the locations HP and LP. + D, Q, and R are 32 bit non-negative integers and HP and LP are + word addresses. The word at LP will contain the lower 31 (not 32) + bits of the result and its most significant bit is set 0. The word + at HP will contain the rest of the result and its MSB is also set 0. + + EXTENDED_DIV(D,H,L,QP,RP) + divides [H:L] by D and saves the quotient and the remainder into + the locations QP and RP, respectively. D, H, L are 32 bit non-negative + integers and QP and RP are word addresses. Here, [H:L] means the + 64 bit integer (imaginary) represented by H and L as follows. + + 63 62 31 30 0 + |0|0||| + + Although [H:L] is 64 bits, you can assume that the quotient is always + represented as 32 bit non-negative integer. +*/ + +#include "ecls.h" + +#ifdef CONVEX + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ + long long int ld, lq, lr, z; + int zh, zl; + + ld = d; + lq = q; + lr = r; + z = ld*lq+lr; + zl = (z & 0x000000007fffffffLL); + zh = (z >> 31LL); + *hp = zh; + *lp = zl; +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + long long int lh, ld, ll; + + ld = d; + lh = h; + ll = l; + lh = (lh << 31LL); + lh = (lh | ll); + *qp = (lh/ld); + *rp = (lh%ld); + } +#endif CONVEX + +#ifdef i386 + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ asm("pushl %ecx"); + asm("movl 8(%ebp),%eax"); + asm("mull 12(%ebp)"); + asm("addl 16(%ebp),%eax"); + asm("adcl $0,%edx"); + asm("shll $1,%edx"); + asm("btrl $31,%eax"); + asm("adcl $0,%edx"); + asm("movl 20(%ebp),%ecx"); + asm("movl %edx, (%ecx)"); + asm("movl 24(%ebp), %ecx"); + asm("movl %eax, (%ecx)"); + asm("popl %ecx"); +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + asm("pushl %ebx"); + asm("movl 12(%ebp),%edx"); + asm("movl 16(%ebp),%eax"); + asm("btl $0,%edx"); + asm("jae 1f"); + asm("btsl $31,%eax"); + asm("1: shrl $1,%edx"); + asm("idivl 8(%ebp)"); + asm("movl 20(%ebp),%ebx"); + asm("movl %eax,(%ebx)"); + asm("movl 24(%ebp),%ebx"); + asm("movl %edx,(%ebx)"); + asm("popl %ebx"); +} +#endif i386 + +#ifdef IBMRT + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ + /* d=L750+20, q=L750+24, etc. */ + asm(" get r0,L750+20(r13)"); /* get an argument */ + asm(" mts r10,r0"); /* put in MQ */ + asm(" get r2,L750+24(r13)"); /* get the other argument */ + asm(" s r0,r0"); /* zero partial product. set carry to 1. */ + asm(" m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2 + m r0,r2"); + /* Now (r0)//mq has the 64 bit product; overflow is ignored. */ + asm(" mfs r10,r2"); /* set r2 = low order word of result + * so product is in (r0)//(r2). + */ + /* + * Force product into two single precision words. + */ + + asm(" get r3,$1f + sli r0,1 + ar2,r2 + bnc0r r3"); /* branch if carry = 0 */ + asm(" oil r0,r0,1 + 1: + sri r2,1"); + /* Now add in the third argument. */ + asm(" get r4,$2f + get r3,L750+28(r13) + a r2,r3 + + bnmr r4"); /* branch if not minus */ + asm(" clrbu r2,0 + lis r3,1 + a r0,r3 + 2: + + get r3,L750+32(r13) + put r0,0(r3) + get r3,L750+36(r13) + put r2,0(r3) + "); +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + /* d=L754+20, h=L754+24, etc. */ + /* Move arguments into registers. */ + asm(" get r0,L754+28(r13)"); /* Low order word of dividend. */ + asm(" get r2,L754+24(r13)"); /* High order word of dividend. */ + asm(" mttbil r2,15 + mftbiu r0,0 + sri r2,1 + mts r10,r0 + get r3,L754+20(r13)") /* Divisor. */ + /* Perform 32 steps of division. */ + asm(" d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3 + d r2,r3"); + /* Now MQ has the quotient, R2 the remainder, and R3 is + * the unchanged divisor. */ + asm(" mttbiu r2,0"); /* Do add-back if necessary. */ + asm(" jntb 1f + a r2,r3 + 1: + mfs r10,r0 + c r2,r3"); /* Remainder : divisor. */ + asm(" jne 2f + inc r0,1 + x r2,r2 + 2:"); + /* Now r0 has the quotient and r2 has the remainder. */ + asm(" get r3,L754+32(r13)"); /* Quotient address. */ + asm(" put r0,0(r3)"); + asm(" get r3,L754+36(r13)"); /* Remainder address. */ + asm(" put r2,0(r3)"); +} + +#endif IBMRT + +#if defined(NEWS) || defined(MAC) + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ + asm(" move.l d2,-(sp) + clr.l d2 + move.l (8,fp),d0 + mulu.l (12,fp),d1:d0 + add.l (16,fp),d0 + addx.l d2,d1 + lsl.l #1,d0 + roxl.l #1,d1 + lsr.l #1,d0 + move.l (20,fp),a0 + move.l d1,(a0) + move.l (24,a6),a0 + move.l d0,(a0)"); +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + asm("movem.l (12,fp),#0x303 + lsl.l #1,d1 + lsr.l #1,d0 + roxr.l #1,d1 + divu.l (8,fp),d0:d1 + move.l d0,(a1) + move.l d1,(a0) + "); +} + +#endif NEWS + +#ifdef __mips + + /* earith.s for MIPS R2000 processor + by Doug Katzman + version 2.1.d dated 7/13/89 15:31 EDT */ + +/* Register names: +#define v0 $2 return value +#define v1 $3 +#define a0 $4 argument registers +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t7 $15 +*/ + +static void +extended_mul(unsigned int d, unsigned int q, unsigned int r, unsigned int *hp, + unsigned int *lp) +{ + asm("mult $4, $5"); /* [hi:lo] = d * q */ + asm("mfhi $5"); /* a1 = hi */ + asm("sll $5, 1"); + asm("mflo $4"); + asm("srl $15, $4, 31"); + asm("and $4, 0x7fffffff"); + asm("or $5, $15"); + asm("addu $4, $6"); /* [a1:a0] += r */ + asm("srl $15, $4, 31"); + asm("and $4, 0x7fffffff"); + asm("addu $5, $15"); + asm("sw $5, 0($7)"); /* *hp = a1 */ +#ifdef __GNUC__ + asm("lw $7, %0" :: "g" (lp)); +#else + asm("lw $7, 16($sp)"); /* fetch fifth actual argument from stack */ +#endif __GNUC__ + asm("sw $4, 0($7)"); /* *lp = a0 */ +} + +static void +extended_div(unsigned int d, unsigned int h, unsigned int l, unsigned int *qp, + unsigned int *rp) +{ + + asm("sll $6, 1"); + asm("li $2, 31"); /* v0 holds number of shifts */ + asm("loop: + srl $15, $6, 31"); + asm("sll $5, 1"); + asm("or $5, $15"); + asm("sll $6, 1"); + asm("subu $15, $5, $4"); /* t = h - d */ + asm("bltz $15, underflow"); + asm("move $5, $15"); + asm("or $6, 1"); + asm("underflow: + subu $2, 1"); + asm("bnez $2, loop"); + asm("sw $6, 0($7)"); /* *qp = l */ +#ifdef __GNUC__ + asm("lw $7, %0" :: "g" (rp)); +#else + asm("lw $7, 16($sp)"); /* fetch fifth actual argument from stack */ +#endif __GNUC__ + asm("sw $5, 0($7)"); /* *rp = h */ +} +#endif __mips + +#if defined(sun3) || (defined __NeXT) + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ + asm(" + movl d2,a7@- + clrl d2 + movl a6@(8),d0 + mulul a6@(12),d1:d0 + addl a6@(16),d0 + addxl d2,d1 + lsll #1,d0 + roxll #1,d1 + lsrl #1,d0 + movl a6@(20),a0 + movl d1,a0@ + movl a6@(24),a0 + movl d0,a0@ + movl a7@+,d2 + "); +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + asm("moveml a6@(12),#0x303 + lsll #1,d1 + lsrl #1,d0 + roxrl #1,d1 + divul a6@(8),d0:d1 + movl d0,a1@ + movl d1,a0@ + "); +} + +#endif sun3 + +/* Possible assembler version: +#ifdef sparc +_extended_mul: +!#PROLOGUE# 0 +!#PROLOGUE# 1 + save %sp,-96,%sp + mov %i0,%o0 + call .umul,2 + mov %i1,%o1 + addcc %o0,%i2,%i0 + addx %o1,0,%o1 + sll %o1,1,%o1 + tst %i0 + bge L77003 + sethi %hi(0x7fffffff),%o3 + or %o3,%lo(0x7fffffff),%o3 ! [internal] + and %i0,%o3,%i0 + inc %o1 +L77003: + st %i0,[%i4] + st %o1,[%i3] + ret + restore %g0,0,%o0 + +#endif sparc +*/ + +#if defined(sparc) || defined(APOLLO) || defined(hpux) || defined(UNIGRAPH)n + +/* for the time being use the C version:*/ + +static void +extended_mul(unsigned int d, unsigned int q, unsigned int r, unsigned int *hp, + unsigned int *lp) +{ + register unsigned short dlo = d & 0xffff, + dhi = d >> 16, + qlo = q & 0xffff, + qhi = q >> 16; + unsigned int d0 = dhi * qlo + dlo * qhi, + d1 = dhi * qhi, + d2 = dlo * qlo; + + d1 = (d1 << 1) + (d0 >> 15); /* add 17 MSB of d0 */ + d1 += d2 >> 31; /* add MSB of d2 */ + d2 &= 0x7fffffff; /* clear MSB of d2 */ + d2 += (d0 & 0x7fff) << 16; /* add 15 LSB of d0: no overflow occurs */ + d1 += d2 >> 31; /* add MSB of d2 */ + d2 &= 0x7fffffff; /* clear MSB of d2 */ + d2 += r; + d1 += d2 >> 31; /* add MSB of d2 */ + d2 &= 0x7fffffff; /* clear MSB of d2 */ + + *hp = d1; + *lp = d2; +} + +static void +extended_div(unsigned int d, unsigned int h, unsigned int l, unsigned int *qp, + unsigned int *rp) +{ + int i; + int borrow; + + l = (l << 1) | 1; + + for (i = 31; i >= 0;) { + + if (h >= d) { + h -= d; + borrow = 0; + } + else + borrow = 1; + + if (i--) + h = (h << 1) | ((unsigned)l >> 31); + + l = (l << 1) | borrow; + + } + + l = - l - 1; + + *qp = l; + *rp = h; +} + +#endif sparc + +#ifdef vax + +static void +extended_mul(int d, int q, int r, int *hp, int *lp) +{ + asm(" emul 4(ap),8(ap),12(ap),r0"); + asm(" ashq $1,r0,r0"); + asm(" rotl $-1,r0,r0"); + asm(" movl r0,*20(ap)"); + asm(" movl r1,*16(ap)"); +} + +static void +extended_div(int d, int h, int l, int *qp, int *rp) +{ + asm(" clrl r0"); + asm(" movl 8(ap),r1"); + asm(" ashq $-1,r0,r0"); + asm(" addl2 12(ap),r0"); + asm(" ediv 4(ap),r0,*16(ap),*20(ap)"); +} +#endif vax diff --git a/src/c/error.d b/src/c/error.d new file mode 100644 index 000000000..cda422537 --- /dev/null +++ b/src/c/error.d @@ -0,0 +1,379 @@ +/* + error.c -- Error handling. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +cl_object Sarithmetic_error, Scell_error, Scondition; +cl_object Scontrol_error, Sdivision_by_zero, Send_of_file; +cl_object Serror, Sfile_error, Sfloating_point_inexact; +cl_object Sfloating_point_invalid_operation, Sfloating_point_overflow; +cl_object Sfloating_point_underflow, Spackage_error, Sparse_error; +cl_object Sprint_not_readable, Sprogram_error, Sreader_error; +cl_object Sserious_condition, Ssimple_condition, Ssimple_error; +cl_object Ssimple_type_error, Ssimple_warning, Sstorage_condition; +cl_object Sstream_error, Sstyle_warning, Stype_error, Sunbound_slot; +cl_object Sunbound_variable, Sundefined_function, Swarning; + +cl_object siSsimple_program_error, siSsimple_control_error; + +cl_object Kpathname; /* file-error */ +cl_object Kdatum, Kexpected_type; /* type-error */ +cl_object Kformat_control, Kformat_arguments; /* simple-condition */ + +/******************************* ------- ******************************/ + +void +cs_overflow(void) +{ +#ifdef DOWN_STACK + if (cs_limit < cs_org - cssize) + cs_limit -= CSGETA; +#else + if (cs_limit > cs_org + cssize) + cs_limit += CSGETA; +#endif + FEerror("Control stack overflow.", 0); +} + +void +error(const char *s) +{ + printf("\nUnrecoverable error: %s\n", s); + fflush(stdout); +#ifdef SIGIOT + signal(SIGIOT, SIG_DFL); /* avoid getting into a loop with abort */ +#endif + abort(); +} + +void +internal_error(const char *s) +{ + printf("\nInternal error in %s()\n", s); + fflush(stdout); +#ifdef SIGIOT + signal(SIGIOT, SIG_DFL); /* avoid getting into a loop with abort */ +#endif + abort(); +} + +/*****************************************************************************/ +/* Support for Lisp Error Handler */ +/*****************************************************************************/ + +cl_object siSuniversal_error_handler; + +cl_object null_string; + +cl_object siSterminal_interrupt; + +void +terminal_interrupt(bool correctable) +{ + funcall(2, siSterminal_interrupt, correctable? Ct : Cnil); +} + +void +FEerror(char *s, int narg, ...) +{ + va_list args; + cl_object rest = Cnil, *r = &rest; + + va_start(args, narg); + while (narg--) + r = &CDR(*r = CONS(va_arg(args, cl_object), Cnil)); + funcall(4, siSuniversal_error_handler, + Cnil, /* not correctable */ + make_simple_string(s), /* condition text */ + rest); +} + +cl_object +CEerror(char *err, int narg, ...) +{ + int i = narg; + va_list args; + cl_object rest = Cnil, *r = &rest; + + va_start(args, narg); + while (i--) + r = &CDR(*r = CONS(va_arg(args, cl_object), Cnil)); + return funcall(4, siSuniversal_error_handler, + Ct, /* correctable */ + make_simple_string(err), /* continue-format-string */ + rest); +} + +/*********************** + * Conditions signaler * + ***********************/ + +void +FEcondition(int narg, cl_object name, ...) +{ + va_list args; + cl_object rest = Cnil, *r = &rest; + + va_start(args, name); + while (--narg) { + *r = CONS(va_arg(args, cl_object), Cnil); + r = &CDR(*r); + } + funcall(4, siSuniversal_error_handler, + Cnil, /* not correctable */ + name, /* condition name */ + rest); +} + +void +FEprogram_error(const char *s, int narg, ...) +{ + va_list args; + cl_object rest = Cnil, *r = &rest; + + gc(t_contiguous); + va_start(args, narg); + while (narg--) { + *r = CONS(va_arg(args, cl_object), Cnil); + printf("%d\n",type_of(CAR(*r))); + r = &CDR(*r); + } + funcall(4, siSuniversal_error_handler, + Cnil, /* not correctable */ + siSsimple_program_error, /* condition name */ + list(4, Kformat_control, make_simple_string(s), + Kformat_arguments, rest)); +} + +void +FEcontrol_error(const char *s, int narg, ...) +{ + va_list args; + cl_object rest = Cnil, *r = &rest; + + va_start(args, narg); + while (narg--) { + *r = CONS(va_arg(args, cl_object), Cnil); + r = &CDR(*r); + } + funcall(4, siSuniversal_error_handler, + Cnil, /* not correctable */ + siSsimple_control_error, /* condition name */ + list(4, Kformat_control, make_simple_string(s), + Kformat_arguments, rest)); +} + +void +FEcannot_open(cl_object fn) +{ + FEcondition(3, Sfile_error, Kpathname, fn); +} + +void +FEend_of_file(cl_object strm) +{ + FEcondition(3, Send_of_file, Kstream, strm); +} + +void +FEwrong_type_argument(cl_object type, cl_object value) +{ + FEcondition(5, Stype_error, Kdatum, value, Kexpected_type, type); +} + +void +FEunbound_variable(cl_object sym) +{ + FEcondition(3, Sunbound_variable, Kname, sym); +} + +void +FEundefined_function(cl_object fname) +{ + FEcondition(3, Sundefined_function, Kname, fname); +} + +/************* + * Shortcuts * + *************/ + +void +FEtoo_few_arguments(int *nargp) +{ + cl_object fname = ihs_top_function_name(); + FEprogram_error("Function ~S requires more than ~R argument~:p.", + 2, fname, MAKE_FIXNUM(*nargp)); +} + +void +FEtoo_many_arguments(int *nargp) +{ + cl_object fname = ihs_top_function_name(); + FEprogram_error("Function ~S requires less than ~R argument~:p.", + 2, fname, MAKE_FIXNUM(*nargp)); +} + +void +FEinvalid_macro_call(cl_object name) +{ + FEerror("Invalid macro call to ~S.", 1, name); +} + +void +FEinvalid_variable(char *s, cl_object obj) +{ + FEerror(s, 1, obj); +} + +void +FEassignment_to_constant(cl_object v) +{ + FEprogram_error("SETQ: Tried to assign a value to the constant ~S.", 1, v); +} + +void +FEinvalid_function(cl_object obj) +{ + FEwrong_type_argument(Sfunction, obj); +} + +/* bootstrap version */ +@(defun si::universal_error_handler (c err args) +@ + printf("\nLisp initialization error.\n"); + Lprint(1, err); + Lprint(1, args); +#ifndef ALFA + exit(0); +#endif +@) + +void +check_arg_failed(int narg, int req) +{ + cl_object fname = ihs_top_function_name(); + FEprogram_error((narg < req) + ? "Function ~S requires ~R argument~:p,~%\ +but only ~R ~:*~[were~;was~:;were~] supplied." + : "Function ~S requires only ~R argument~:p,~%\ +but ~R ~:*~[were~;was~:;were~] supplied.", + 3, fname, MAKE_FIXNUM(req), MAKE_FIXNUM(narg)); +} + +void +illegal_index(cl_object x, cl_object i) +{ + FEerror("~S is an illegal index to ~S.", 2, i, x); +} + +void +FEtype_error_symbol(cl_object obj) +{ + FEwrong_type_argument(Ssymbol, obj); +} + +void +not_a_variable(cl_object obj) +{ + FEinvalid_variable("~S is not a variable.", obj); +} + +/************************************ + * Higher level interface to errors * + ************************************/ + +@(defun error (eformat &rest args) + int i; + cl_object rest = Cnil, *r = &rest; +@ + for (i=narg-1; i; i--) { + *r = CONS(va_arg(args, cl_object), Cnil); + r = &CDR(*r); + } + funcall(4, siSuniversal_error_handler, + Cnil, + eformat, + rest); +@) + +@(defun cerror (cformat eformat &rest args) + int i; + cl_object rest = Cnil, *r = &rest; +@ + for (i=narg-2; i; i--) { + *r = CONS(va_arg(args, cl_object), Cnil); + r = &CDR(*r); + } + return(funcall(4, siSuniversal_error_handler, + cformat, + eformat, + rest)); +@) + +#if defined(FRAME_CHAIN) && !defined(RUNTIME) +static char * +get_current_frame(void) +{ + char *frame; + GET_CURRENT_FRAME(frame); + return frame; +} + +@(defun si::backtrace () + char *this_frame, *next_frame, *next_pc; + bool first = TRUE; + cl_object sym; + jmp_buf buf; +@ + /* ensure flushing of register caches */ + if (ecls_setjmp(buf) == 0) ecls_longjmp(buf, 1); + + this_frame = get_current_frame(); + while (TRUE) { + next_frame = FRAME_CHAIN(this_frame); + next_pc = FRAME_SAVED_PC(this_frame); +#ifdef DOWN_STACK + if (next_frame == 0 || next_frame > (char *)cs_org) break; +#else + if (next_frame < (char *)cs_org) break; +#endif + sym = (cl_object)get_function_entry(next_pc); + if (sym) { + if (!first) + printf(" < "); + else + first = FALSE; + princ(sym, Cnil); + } +/* + else + printf("FP: 0x%x, PC: 0x%x\n", next_frame, next_pc); +*/ + this_frame = next_frame; + } + @(return) +@) +#endif + +void +init_error(void) +{ + null_string = make_simple_string(""); + register_root(&null_string); +} diff --git a/src/c/eval.d b/src/c/eval.d new file mode 100644 index 000000000..b789f228c --- /dev/null +++ b/src/c/eval.d @@ -0,0 +1,293 @@ +/* + eval.c -- Eval. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +/******************************* EXPORTS ******************************/ + +cl_object Sapply; +cl_object Sfuncall; + +/******************************* ------- ******************************/ + +static struct nil3 { cl_object nil3_self[3]; } three_nils; + +#define SYMBOL_FUNCTION(sym) (SYM_FUN(sym) == OBJNULL ? \ + (FEundefined_function(sym),Cnil) : SYM_FUN(sym)) + +#ifdef THREADS +#define eval1 clwp->lwp_eval1 +#else +static int eval1 = 0; /* = 1 during one-shot bypass of evalhook/applyhook */ +#endif THREADS + +cl_object Vevalhook; +cl_object Vapplyhook; + +/* Calling conventions: + Compiled C code calls lisp function supplying #args, and args. + Linking function performs check_args, gets jmp_buf with _setjmp, then + if cfun then stores C code address into function link location + and transfers to jmp_buf at cf_self + if cclosure then replaces #args with cc_env and calls cc_self + otherwise, it emulates funcall. + */ + +/* + *---------------------------------------------------------------------- + * + * apply -- + * applies a Lisp function to the arguments in array args. + * narg is their count. + * + * Results: + * number of values + * + * Side Effect: + * values are placed into the array Values + *---------------------------------------------------------------------- + */ +cl_object +apply(int narg, cl_object fun, cl_object *args) +{ + cl_object x = fun; + + AGAIN: + if (fun == OBJNULL) + FEundefined_function(x); + + switch (type_of(fun)) { + case t_cfun: + return APPLY(narg, fun->cfun.entry, args); + + case t_cclosure: + return APPLY_closure(narg, fun->cclosure.entry, fun->cclosure.env, args); + +#ifdef CLOS + case t_gfun: + return gcall(narg, fun, args); +#endif + + case t_symbol: + fun = SYM_FUN(fun); + goto AGAIN; + + case t_bytecodes: + { + cl_object mv_values[narg]; /* __GNUC__ */ + /* move args out of VALUES, or macroexpand of fun's body + will clobber them */ + memcpy(mv_values, args, narg * sizeof(cl_object)); + return lambda_apply(narg, fun, mv_values); + } + break; + default: + } + FEinvalid_function(fun); +} + +cl_return +funcall(int narg, ...) +{ + cl_object fun, x; + va_list funargs; + va_start(funargs, narg); + fun = va_arg(funargs, cl_object); + + AGAIN: + if (fun == OBJNULL) { + va_start(funargs, narg); + FEundefined_function(va_arg(funargs, cl_object)); + } + switch (type_of(fun)) { + case t_cfun: + return APPLY(narg-1, fun->cfun.entry, funargs); + + case t_cclosure: + return APPLY_closure(narg-1, fun->cclosure.entry, fun->cclosure.env, funargs); + +#ifdef CLOS + case t_gfun: + return gcall(narg-1, fun, funargs); +#endif + + case t_symbol: + fun = SYM_FUN(fun); + goto AGAIN; + + case t_bytecodes: + return lambda_apply(narg-1, fun, (cl_object *)funargs); + + default: + } + FEinvalid_function(fun); +} + +/*----------------------------------------------------------------------* + * Linking mechanism * + *----------------------------------------------------------------------*/ + +static cl_object siSlink_to; +static cl_object siSlink_from; + +cl_object +#ifdef CLOS +link_call(cl_object sym, cl_object (**pLK)(), cl_object *gfun, cl_object *args) +#else +link_call(cl_object sym, cl_object (**pLK)(), cl_object *args) +#endif CLOS +{ int narg = (int)args[0]; + cl_object fun = symbol_function(sym); + + if (fun == OBJNULL) FEerror("Undefined function.", 0); + + switch (type_of(fun)) { + case t_cfun: + putprop(sym, CONS(CONS(MAKE_FIXNUM((int)pLK), + MAKE_FIXNUM((int)*pLK)), + getf(sym->symbol.plist, siSlink_from, Cnil)), + siSlink_from); + *pLK = fun->cfun.entry; + return APPLY(narg, fun->cfun.entry, &args[1]); +#ifdef CLOS + case t_gfun: + putprop(sym, CONS(CONS(MAKE_FIXNUM((int)gfun), + MAKE_FIXNUM((int)OBJNULL)), + getf(sym->symbol.plist, siSlink_from, Cnil)), + siSlink_from); + *gfun = fun; + return gcall(narg, fun, &args[1]); +#endif CLOS + case t_cclosure: + args[0] = (cl_object)fun->cclosure.env; + return APPLY(narg+1, fun->cclosure.entry, args); + + case t_bytecodes: + return lambda_apply(narg, fun, &args[1]); + + default: + FEinvalid_function(fun); + } +} + +@(defun si::unlink_symbol (s) + cl_object pl; +@ + if (!SYMBOLP(s)) + FEtype_error_symbol(s); + pl = getf(s->symbol.plist, siSlink_from, Cnil); + if (!endp(pl)) { + for (; !endp(pl); pl = CDR(pl)) + *(int *)(fix(CAAR(pl))) = fix(CDAR(pl)); + remf(&s->symbol.plist, siSlink_from); + } + @(return) +@) + +@(defun funcall (fun &rest args) +@ + return(apply(narg-1, fun, (cl_object *)args)); +@) + +@(defun apply (fun lastarg &rest args) + int i; +@ + narg -= 2; + for (i = 0; narg; narg--) { + VALUES(i++) = lastarg; + lastarg = va_arg(args, cl_object); + } + loop_for_in (lastarg) { + VALUES(i++) = CAR(lastarg); + } end_loop_for_in; + { + cl_object savargs[i]; + memcpy(savargs, &VALUES(0), i*sizeof(cl_object)); + return apply(i, fun, savargs); + } +@) + +@(defun eval (form) + cl_object output, lex_old = lex_env; +@ + lex_new(); + output = eval(form, NULL); + lex_env = lex_old; + returnn(output); +@) + +@(defun evalhook (form evalhookfn applyhookfn &optional (env Cnil)) + cl_object output, lex_old = lex_env; + bds_ptr old_bds_top = bds_top; +@ + lex_env = env; + lex_copy(); + bds_bind(Vevalhook, evalhookfn); + bds_bind(Vapplyhook, applyhookfn); + eval1 = 1; + output = eval(form, NULL); + bds_unwind(old_bds_top); + lex_env = lex_old; + returnn(output); +@) + +@(defun applyhook (fun args evalhookfn applyhookfn) + bds_ptr old_bds_top = bds_top; +@ + bds_bind(Vevalhook, evalhookfn); + bds_bind(Vapplyhook, applyhookfn); + VALUES(0) = Lapply(2, fun, args); + bds_unwind(old_bds_top); + returnn(VALUES(0)); +@) + +@(defun constantp (arg) + cl_object flag; +@ + switch (type_of(arg)) { + case t_cons: + flag = (CAR(arg) == Squote) ? Ct : Cnil; + break; + case t_symbol: + flag = (arg->symbol.stype == stp_constant) ? Ct : Cnil; + break; + default: + flag = Ct; + } + @(return flag) +@) + +void +init_eval(void) +{ + make_constant("CALL-ARGUMENTS-LIMIT", MAKE_FIXNUM(64)); + + SYM_VAL(Vevalhook) = Cnil; + SYM_VAL(Vapplyhook) = Cnil; + + eval1 = 0; + + three_nils.nil3_self[0] = Cnil; + three_nils.nil3_self[1] = Cnil; + three_nils.nil3_self[2] = Cnil; + + siSlink_from = make_si_ordinary("LINK-FROM"); + register_root(&siSlink_from); + siSlink_to = make_si_ordinary("LINK-TO"); + register_root(&siSlink_to); +} diff --git a/src/c/file.d b/src/c/file.d new file mode 100644 index 000000000..ad56d0854 --- /dev/null +++ b/src/c/file.d @@ -0,0 +1,1601 @@ +/* + file.d -- File interface. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +/* + IMPLEMENTATION-DEPENDENT + + The file contains code to reclaim the I/O buffer + by accessing the FILE structure of C. +*/ + +#include + +#if defined(BSD) && !defined(MSDOS) +#include +#endif + +/******************************* EXPORTS ******************************/ +cl_object Vstandard_input; +cl_object Vstandard_output; +cl_object Verror_output; +cl_object Vquery_io; +cl_object Vdebug_io; +cl_object Vterminal_io; +cl_object Vtrace_output; + +cl_object Kabort; +cl_object Kdirection; +cl_object Kinput; +cl_object Koutput; +cl_object Kio; +cl_object Kprobe; +cl_object Kelement_type; +cl_object Kdefault; +cl_object Kif_exists; +cl_object Kerror; +cl_object Knew_version; +cl_object Krename; +cl_object Krename_and_delete; +cl_object Koverwrite; +cl_object Kappend; +cl_object Ksupersede; +cl_object Kcreate; +cl_object Kprint; +cl_object Kif_does_not_exist; +cl_object Kset_default_pathname; + +/******************************* ------- ******************************/ + +static cl_object terminal_io; + +cl_object siVignore_eof_on_terminal_io; + +static bool +feof1(FILE *fp) +{ + if (!feof(fp)) + return(FALSE); + if (fp == terminal_io->stream.object0->stream.file) { + if (Null(symbol_value(siVignore_eof_on_terminal_io))) + return(TRUE); +#ifdef unix + fp = freopen("/dev/tty", "r", fp); +#endif + if (fp == NULL) + error("can't reopen the console"); + return(FALSE); + } + return(TRUE); +} + +#undef feof +#define feof feof1 + +/*---------------------------------------------------------------------- + * Input_stream_p(strm) answers + * if stream strm is an input stream or not. + * It does not check if it really is possible to read + * from the stream, + * but only checks the mode of the stream (sm_mode). + *---------------------------------------------------------------------- + */ +bool +input_stream_p(cl_object strm) +{ +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_io: + case smm_input: + case smm_concatenated: + case smm_two_way: + case smm_echo: + case smm_string_input: + return(TRUE); + + case smm_output: + case smm_probe: + case smm_string_output: + case smm_broadcast: + return(FALSE); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + default: + error("illegal stream mode"); + } +} + +/*---------------------------------------------------------------------- + * Output_stream_p(strm) answers + * if stream strm is an output stream. + * It does not check if it really is possible to write + * to the stream, + * but only checks the mode of the stream (sm_mode). + *---------------------------------------------------------------------- + */ +bool +output_stream_p(cl_object strm) +{ +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(FALSE); + + case smm_input: + case smm_probe: + case smm_concatenated: + case smm_string_input: + return(FALSE); + + case smm_output: + case smm_io: + case smm_two_way: + case smm_echo: + case smm_broadcast: + case smm_string_output: + return(TRUE); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + default: + error("illegal stream mode"); + } +} + +cl_object +stream_element_type(cl_object strm) +{ + cl_object x; + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(FALSE); + + case smm_input: + case smm_output: + case smm_io: + case smm_probe: + return(strm->stream.object0); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + x = strm->stream.object0; + if (endp(x)) + return(Ct); + return(stream_element_type(CAR(x))); + + case smm_concatenated: + x = strm->stream.object0; + if (endp(x)) + return(Ct); + return(stream_element_type(CAR(x))); + + case smm_two_way: + case smm_echo: + return(stream_element_type(strm->stream.object0)); + + case smm_string_input: + case smm_string_output: + return(Sbase_char); + + default: + error("illegal stream mode"); + } +} + +/*---------------------------------------------------------------------- + * Error messages + *---------------------------------------------------------------------- + */ + +static void cannot_create(cl_object fn) __attribute__((noreturn)); +static void cannot_read(cl_object fn) __attribute__((noreturn)); +static void cannot_write(cl_object fn) __attribute__((noreturn)); +static void internal_stream_error(const char *routine, cl_object strm) __attribute__((noreturn)); + +static void +cannot_create(cl_object fn) +{ + FEerror("Cannot create the file ~A.", 1, fn); +} + +static void +cannot_read(cl_object strm) +{ + FEerror("Cannot read the stream ~S.", 1, strm); +} + +static void +cannot_write(cl_object strm) +{ + FEerror("Cannot write to the stream ~S.", 1, strm); +} + +static void +internal_stream_error(const char *routine, cl_object strm) +{ + FEerror("~A : internal error, closed stream ~S without smm_mode flag.", + 2, make_simple_string(routine), strm); +} + +void +closed_stream(cl_object strm) +{ + FEerror("The stream ~S is already closed.", 1, strm); +} + +/*---------------------------------------------------------------------- + * Open_stream(fn, smm, if_exists, if_does_not_exist) + * opens file fn with mode smm. + * Fn is a pathname designator. + *---------------------------------------------------------------------- + */ +cl_object +open_stream(cl_object fn, enum smmode smm, cl_object if_exists, + cl_object if_does_not_exist) +{ + cl_object x; + FILE *fp; + char *fname = coerce_to_filename(fn)->string.self; + + if (smm == smm_input || smm == smm_probe) { + fp = fopen(fname, OPEN_R); + if (fp == NULL) { + if (if_does_not_exist == Kerror) + FEcannot_open(fn); + else if (if_does_not_exist == Kcreate) { + fp = fopen(fname, OPEN_W); + if (fp == NULL) + cannot_create(fn); + fclose(fp); + fp = fopen(fname, OPEN_R); + if (fp == NULL) + FEcannot_open(fn); + } else if (Null(if_does_not_exist)) + return(Cnil); + else + FEerror("~S is an illegal IF-DOES-NOT-EXIST option.", + 1, if_does_not_exist); + } + } else if (smm == smm_output || smm == smm_io) { + if (if_exists == Knew_version && if_does_not_exist == Kcreate) + goto CREATE; + fp = fopen(fname, OPEN_R); + if (fp != NULL) { + fclose(fp); + if (if_exists == Kerror) + FEerror("The file ~A already exists.", 1, fn); + else if (if_exists == Krename) { + fp = backup_fopen(fname, (smm == smm_output) + ? OPEN_W + : OPEN_RW); + if (fp == NULL) + cannot_create(fn); + } else if (if_exists == Krename_and_delete || + if_exists == Knew_version || + if_exists == Ksupersede) { + fp = fopen(fname, (smm == smm_output) + ? OPEN_W + : OPEN_RW); + if (fp == NULL) + cannot_create(fn); + } else if (if_exists == Koverwrite) { + fp = fopen(fname, OPEN_RW); + if (fp == NULL) + FEcannot_open(fn); + } else if (if_exists == Kappend) { + fp = fopen(fname, (smm == smm_output) + ? OPEN_A + : OPEN_RA); + if (fp == NULL) + FEerror("Cannot append to the file ~A.",1,fn); + } else if (Null(if_exists)) + return(Cnil); + else + FEerror("~S is an illegal IF-EXISTS option.", + 1, if_exists); + } else { + if (if_does_not_exist == Kerror) + FEerror("The file ~A does not exist.", 1, fn); + else if (if_does_not_exist == Kcreate) { + CREATE: + fp = fopen(fname, (smm == smm_output) + ? OPEN_W + : OPEN_RW); + if (fp == NULL) + cannot_create(fn); + } else if (Null(if_does_not_exist)) + return(Cnil); + else + FEerror("~S is an illegal IF-DOES-NOT-EXIST option.", + 1, if_does_not_exist); + } + } else + error("illegal stream mode"); + x = alloc_object(t_stream); + x->stream.mode = (short)smm; + x->stream.file = fp; + x->stream.object0 = Sbase_char; + x->stream.object1 = fn; + x->stream.int0 = x->stream.int1 = 0; +#if !defined(GBC_BOEHM) + fp->_IO_buf_base = NULL; /* BASEFF; */ + setbuf(fp, x->stream.buffer = alloc(BUFSIZ)); +#endif + return(x); +} + + +/*---------------------------------------------------------------------- + * Close_stream(strm, abort_flag) closes stream strm. + * The abort_flag is not used now. + *---------------------------------------------------------------------- + */ +void +close_stream(cl_object strm, bool abort_flag) /* Not used now! */ +{ + FILE *fp; + + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + /* It is permissible to close a closed stream, although the output + is unspecified in those cases. */ + break; + + case smm_output: + if (fp == stdout) + FEerror("Cannot close the standard output.", 0); + if (fp == NULL) + internal_stream_error("close_stream", strm); + fflush(fp); + fclose(fp); +#if !defined(GBC_BOEHM) + dealloc(strm->stream.buffer, BUFSIZ); + strm->stream.buffer = NULL; +#endif + strm->stream.file = NULL; + break; + + case smm_input: + if (fp == stdin) + FEerror("Cannot close the standard input.", 0); + + case smm_io: + case smm_probe: + if (fp == NULL) + internal_stream_error("close_stream", strm); + fclose(fp); +#if !defined(GBC_BOEHM) + dealloc(strm->stream.buffer, BUFSIZ); + strm->stream.file = NULL; +#endif + break; +#if 0 + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + close_stream(CAR(x), abort_flag); + strm->stream.object0 = Cnil; + break; + + case smm_concatenated: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + close_stream(CAR(x), abort_flag); + break; + + case smm_two_way: + close_stream(strm->stream.object0, abort_flag); + close_stream(strm->stream.object1, abort_flag); + break; + + case smm_echo: + close_stream(strm->stream.object0, abort_flag); + close_stream(strm->stream.object1, abort_flag); + break; + + case smm_string_input: + break; /* There is nothing to do. */ + + case smm_string_output: + break; /* There is nothing to do. */ +#else + case smm_synonym: + case smm_broadcast: + case smm_concatenated: + case smm_two_way: + case smm_echo: + case smm_string_input: + case smm_string_output: + /* The elements of a composite stream are not closed. For + composite streams we zero object1. For files we do not, + as it might contain an useful pathname */ + strm->stream.object1 = OBJNULL; + break; +#endif + default: + error("illegal stream mode"); + } + strm->stream.mode = smm_closed; + strm->stream.file = NULL; + strm->stream.object0 = OBJNULL; +} + +cl_object +make_two_way_stream(cl_object istrm, cl_object ostrm) +{ + cl_object strm; + + strm = alloc_object(t_stream); + strm->stream.mode = (short)smm_two_way; + strm->stream.file = NULL; + strm->stream.object0 = istrm; + strm->stream.object1 = ostrm; + strm->stream.int0 = strm->stream.int1 = 0; + return(strm); +} + +cl_object +make_echo_stream(cl_object istrm, cl_object ostrm) +{ + cl_object strm; + + strm = make_two_way_stream(istrm, ostrm); + strm->stream.mode = (short)smm_echo; + return(strm); +} + +cl_object +make_string_input_stream(cl_object strng, cl_index istart, cl_index iend) +{ + cl_object strm; + + strm = alloc_object(t_stream); + strm->stream.mode = (short)smm_string_input; + strm->stream.file = NULL; + strm->stream.object0 = strng; + strm->stream.object1 = OBJNULL; + strm->stream.int0 = istart; + strm->stream.int1 = iend; + return(strm); +} + +cl_object +make_string_output_stream(cl_index line_length) +{ + cl_object strng, strm; + + line_length++; + strng = alloc_object(t_string); + strng->string.hasfillp = TRUE; + strng->string.adjustable = TRUE; + strng->string.displaced = Cnil; + strng->string.dim = line_length; + strng->string.fillp = 0; + strng->string.self = NULL; /* For GC sake */ + strng->string.self = alloc(line_length); + strng->string.self[0] = '\0'; + strm = alloc_object(t_stream); + strm->stream.mode = (short)smm_string_output; + strm->stream.file = NULL; + strm->stream.object0 = strng; + strm->stream.object1 = OBJNULL; + strm->stream.int0 = strm->stream.int1 = 0; + return(strm); +} + +cl_object +get_output_stream_string(cl_object strm) +{ + cl_object strng; + + strng = copy_simple_string(strm->stream.object0); + strm->stream.object0->string.fillp = 0; + return(strng); +} + + + +#ifdef TK +bool no_input = FALSE; + +StdinEnableEvents() +{ + no_input = TRUE; +} + +StdinResume() +{ + no_input = FALSE; +} +# define GETC(c, fp) { if (fp == stdin) \ + while (no_input) Tk_DoOneEvent(0); \ + c = getc(fp); \ + no_input = !FILE_CNT(fp); } +# define UNGETC(c, fp) { if (fp == stdin) no_input = FALSE; ungetc(c, fp); } +#else +# define GETC(c, fp) c = getc(fp) +# define UNGETC(c, fp) ungetc(c, fp) +#endif + +int +readc_stream(cl_object strm) +{ + int c; + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_input: + case smm_io: + if (fp == NULL) + internal_stream_error("readc_stream",strm); + GETC(c, fp); +/* c &= 0377; */ + if (feof(fp)) + FEend_of_file(strm); +/* strm->stream.int0++; useless in smm_io, Beppe */ + return(c); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_concatenated: + { cl_object strmi = strm->stream.object0; + while (!endp(strmi)) { + if (!stream_at_end(CAR(strmi))) + return(readc_stream(CAR(strmi))); + strm->stream.object0 = strmi = CDR(strmi); + } + FEend_of_file(strm); + } + + case smm_two_way: +#ifdef unix + if (strm == terminal_io) /**/ + flush_stream(terminal_io->stream.object1); /**/ +#endif + strm->stream.int1 = 0; + strm = strm->stream.object0; + goto BEGIN; + + case smm_echo: + c = readc_stream(strm->stream.object0); + if (strm->stream.int0 == 0) + writec_stream(c, strm->stream.object1); + else /* don't echo twice if it was unread */ + --(strm->stream.int0); + return(c); + + case smm_string_input: + if (strm->stream.int0 >= strm->stream.int1) + FEend_of_file(strm); + return(strm->stream.object0->string.self[strm->stream.int0++]); + + case smm_output: + case smm_probe: + case smm_broadcast: + case smm_string_output: + cannot_read(strm); + + default: + error("illegal stream mode"); + } +} + +void +unreadc_stream(int c, cl_object strm) +{ + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_input: + case smm_io: + if (fp == NULL) + internal_stream_error("unreadc_stream",strm); + UNGETC(c, fp); +/* --strm->stream.int0; useless in smm_io, Beppe */ + break; + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_concatenated: + if (endp(strm->stream.object0)) + goto UNREAD_ERROR; + strm = CAR(strm->stream.object0); + goto BEGIN; + + case smm_two_way: + strm = strm->stream.object0; + goto BEGIN; + + case smm_echo: + unreadc_stream(c, strm->stream.object0); + (strm->stream.int0)++; + break; + + case smm_string_input: + if (strm->stream.int0 <= 0) + goto UNREAD_ERROR; + --strm->stream.int0; + break; + + case smm_output: + case smm_probe: + case smm_broadcast: + case smm_string_output: + goto UNREAD_ERROR; + + default: + error("illegal stream mode"); + } + return; + +UNREAD_ERROR: + FEerror("Cannot unread the stream ~S.", 1, strm); +} + +int +writec_stream(int c, cl_object strm) +{ + cl_object x; + unsigned char *p; + cl_index i; + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_output: + case smm_io: +/* strm->stream.int0++; useless in smm_io, Beppe */ + if (c == '\n') + strm->stream.int1 = 0; + else if (c == '\t') + strm->stream.int1 = (strm->stream.int1&~07) + 8; + else + strm->stream.int1++; + if (fp == NULL) + internal_stream_error("writec",strm); + putc(c, fp); + break; + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + writec_stream(c, CAR(x)); + break; + + case smm_two_way: + strm->stream.int0++; + if (c == '\n') + strm->stream.int1 = 0; + else if (c == '\t') + strm->stream.int1 = (strm->stream.int1&~07) + 8; + else + strm->stream.int1++; + strm = strm->stream.object1; + goto BEGIN; + + case smm_echo: + strm = strm->stream.object1; + goto BEGIN; + + case smm_string_output: + strm->stream.int0++; + if (c == '\n') + strm->stream.int1 = 0; + else if (c == '\t') + strm->stream.int1 = (strm->stream.int1&~07) + 8; + else + strm->stream.int1++; + x = strm->stream.object0; + if (x->string.fillp >= x->string.dim) { + if (!x->string.adjustable) + FEerror("The string ~S is not adjustable.", + 1, x); +#ifdef THREADS + start_critical_section(); /* avoid losing p */ +#endif THREADS + p = alloc(x->string.dim * 2 + 16); + for (i = 0; i < x->string.dim; i++) + p[i] = x->string.self[i]; + i = x->string.dim * 2 + 16; +#define ADIMLIM 16*1024*1024 + if (i >= ADIMLIM) + FEerror("Can't extend the string.", 0); + x->string.dim = i; + adjust_displaced(x, p - x->string.self); +#ifdef THREADS + end_critical_section(); +#endif THREADS + } + x->string.self[x->string.fillp++] = c; + break; + + case smm_input: + case smm_probe: + case smm_concatenated: + case smm_string_input: + cannot_write(strm); + + default: + error("illegal stream mode"); + } + return(c); +} + +void +writestr_stream(const char *s, cl_object strm) +{ + while (*s != '\0') + writec_stream(*s++, strm); +} + +void +flush_stream(cl_object strm) +{ + cl_object x; + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_output: + case smm_io: + if (fp == NULL) + internal_stream_error("flush_stream",strm); + fflush(fp); + break; + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + flush_stream(CAR(x)); + break; + + case smm_two_way: + case smm_echo: + strm = strm->stream.object1; + goto BEGIN; + + case smm_string_output: { + cl_object strng = strm->stream.object0; + strng->string.self[strng->string.fillp] = '\0'; + break; + } + case smm_input: + case smm_probe: + case smm_concatenated: + case smm_string_input: + FEerror("Cannot flush the stream ~S.", 1, strm); + + default: + error("illegal stream mode"); + } +} + +void +clear_input_stream(cl_object strm) +{ + cl_object x; + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_input: + if (fp == NULL) + internal_stream_error("clear_input_stream",strm); + fseek(fp, 0L, 2); + break; + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + flush_stream(CAR(x)); + break; + + case smm_two_way: + case smm_echo: + strm = strm->stream.object0; + goto BEGIN; + + case smm_string_output: + break; + + case smm_io: + case smm_output: + case smm_probe: + case smm_concatenated: + case smm_string_input: + FEerror("Cannot clear the input of the stream ~S.", 1, strm); + break; + + default: + error("illegal stream mode"); + } +} + +void +clear_output_stream(cl_object strm) +{ + cl_object x; + FILE *fp; + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + break; + + case smm_output: + if (fp == NULL) + internal_stream_error("clear_output_stream",strm); + fseek(fp, 0L, 2); + break; + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_broadcast: + for (x = strm->stream.object0; !endp(x); x = CDR(x)) + flush_stream(CAR(x)); + break; + + case smm_two_way: + case smm_echo: + strm = strm->stream.object1; + goto BEGIN; + + case smm_string_output: + break; + + case smm_io: + case smm_input: + case smm_probe: + case smm_concatenated: + case smm_string_input: + FEerror("Cannot clear the output of the stream ~S.", 1, strm); + break; + + default: + error("illegal stream mode"); + } +} + +bool +stream_at_end(cl_object strm) +{ + int c; + FILE *fp; + +#ifdef CLOS + if (type_of(strm) == t_instance) + return(FALSE); +#endif + +BEGIN: + fp = strm->stream.file; + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(TRUE); + + case smm_io: + case smm_input: + if (fp == NULL) + closed_stream(strm); + GETC(c, fp); + if (feof(fp)) + return(TRUE); + else { + UNGETC(c, fp); + return(FALSE); + } + + case smm_output: + case smm_probe: + case smm_broadcast: + case smm_string_output: + return(FALSE); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_concatenated: + { cl_object strmi = strm->stream.object0; + while (!endp(strmi)) { + if (!stream_at_end(CAR(strmi))) + return(FALSE); + strm->stream.object0 = strmi = CDR(strmi); + } + return(TRUE); + } + + case smm_two_way: +#ifdef unix + if (strm == terminal_io) /**/ + flush_stream(terminal_io->stream.object1); /**/ +#endif + strm = strm->stream.object0; + goto BEGIN; + + case smm_echo: + strm = strm->stream.object0; + goto BEGIN; + + case smm_string_input: + if (strm->stream.int0 >= strm->stream.int1) + return(TRUE); + else + return(FALSE); + + default: + error("illegal stream mode"); + } +} + +bool +listen_stream(cl_object strm) +{ + FILE *fp; + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(FALSE); + + case smm_input: + case smm_io: + fp = strm->stream.file; + if (fp == NULL) + internal_stream_error("listen_stream",strm); + if (feof(fp)) + return(FALSE); + if (FILE_CNT(fp) > 0) + return(TRUE); +#ifdef FIONREAD + { long c = 0; + ioctl(fileno(fp), FIONREAD, &c); + if (c <= 0) + return(FALSE); + } +#endif FIONREAD + return(TRUE); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_concatenated: + if (endp(strm->stream.object0)) + return(FALSE); + strm = CAR(strm->stream.object0); /* Incomplete! */ + goto BEGIN; + + case smm_two_way: + case smm_echo: + strm = strm->stream.object0; + goto BEGIN; + + case smm_string_input: + return(strm->stream.int0 < strm->stream.int1); + + case smm_output: + case smm_probe: + case smm_broadcast: + case smm_string_output: + FEerror("Can't listen to ~S.", 1, strm); + + default: + error("illegal stream mode"); + } +} + +long +file_position(cl_object strm) +{ + FILE *fp; + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(-1); + + case smm_input: + case smm_output: + case smm_io: + /* return(strm->stream.int0); */ + fp = strm->stream.file; + if (fp == NULL) + internal_stream_error("file_position",strm); + return(ftell(fp)); + + case smm_string_output: + return(strm->stream.object0->string.fillp); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_probe: + case smm_broadcast: + case smm_concatenated: + case smm_two_way: + case smm_echo: + case smm_string_input: + return(-1); + + default: + error("illegal stream mode"); + } +} + +long +file_position_set(cl_object strm, long disp) +{ + FILE *fp; + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(-1); + + case smm_input: + case smm_output: + case smm_io: + fp = strm->stream.file; + if (fp == NULL) + internal_stream_error("file_position_set",strm); + if (fseek(fp, disp, 0) < 0) + return(-1); +/* strm->stream.int0 = disp; useless in smm_io, Beppe */ + return(0); + + case smm_string_output: + if (disp < strm->stream.object0->string.fillp) { + strm->stream.object0->string.fillp = disp; + strm->stream.int0 = disp; + } else { + disp -= strm->stream.object0->string.fillp; + while (disp-- > 0) + writec_stream(' ', strm); + } + return(0); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_probe: + case smm_broadcast: + case smm_concatenated: + case smm_two_way: + case smm_echo: + case smm_string_input: + return(-1); + + default: + error("illegal stream mode"); + } +} + +long +file_length(cl_object strm) +{ + FILE *fp; + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(-1); + + case smm_input: + case smm_output: + case smm_io: + fp = strm->stream.file; + if (fp == NULL) + internal_stream_error("file_length",strm); + return(file_len(fp)); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + /* FIXME! Should signal an error of type-error */ + case smm_probe: + case smm_broadcast: + case smm_concatenated: + case smm_two_way: + case smm_echo: + case smm_string_input: + case smm_string_output: + return(-1); + + default: + error("illegal stream mode"); + } +} + +int +file_column(cl_object strm) +{ + +BEGIN: + switch ((enum smmode)strm->stream.mode) { + case smm_closed: + closed_stream(strm); + return(-1); + + case smm_output: + case smm_io: + case smm_two_way: + case smm_string_output: + return(strm->stream.int1); + + case smm_synonym: + strm = symbol_value(strm->stream.object0); + if (type_of(strm) != t_stream) + FEwrong_type_argument(Sstream, strm); + goto BEGIN; + + case smm_echo: + strm = strm->stream.object1; + goto BEGIN; + + case smm_input: + case smm_probe: + case smm_string_input: + return(-1); + + case smm_concatenated: + if (endp(strm->stream.object0)) + return(-1); + strm = CAR(strm->stream.object0); + goto BEGIN; + + case smm_broadcast: + { + int i; + cl_object x; + + for (x = strm->stream.object0; !endp(x); x = CDR(x)) { + i = file_column(CAR(x)); + if (i >= 0) + return(i); + } + return(-1); + } + default: + error("illegal stream mode"); + } +} + +@(defun make_synonym_stream (sym) + cl_object x; +@ + assert_type_symbol(sym); + x = alloc_object(t_stream); + x->stream.mode = (short)smm_synonym; + x->stream.file = NULL; + x->stream.object0 = sym; + x->stream.object1 = OBJNULL; + x->stream.int0 = x->stream.int1 = 0; + @(return x) +@) + + +@(defun make_broadcast_stream (&rest ap) + cl_object x, streams; + int i; +@ + streams = Cnil; + for (i = 0; i < narg; i++) { + x = va_arg(ap, cl_object); + if (type_of(x) != t_stream || !output_stream_p(x)) + cannot_write(x); + streams = CONS(x, streams); + } + x = alloc_object(t_stream); + x->stream.mode = (short)smm_broadcast; + x->stream.file = NULL; + x->stream.object0 = nreverse(streams); + x->stream.object1 = OBJNULL; + x->stream.int0 = x->stream.int1 = 0; + @(return x) +@) + +@(defun make_concatenated_stream (&rest ap) + cl_object x, streams; + int i; +@ + streams = Cnil; + for (i = 0; i < narg; i++) { + x = va_arg(ap, cl_object); + if (type_of(x) != t_stream || !input_stream_p(x)) + cannot_read(x); + streams = CONS(x, streams); + } + x = alloc_object(t_stream); + x->stream.mode = (short)smm_concatenated; + x->stream.file = NULL; + x->stream.object0 = nreverse(streams); + x->stream.object1 = OBJNULL; + x->stream.int0 = x->stream.int1 = 0; + @(return x) +@) + +@(defun make_two_way_stream (strm1 strm2) +@ + if (type_of(strm1) != t_stream || !input_stream_p(strm1)) + cannot_read(strm1); + if (type_of(strm2) != t_stream || !output_stream_p(strm2)) + cannot_write(strm2); + @(return make_two_way_stream(strm1, strm2)) +@) + +@(defun make_echo_stream (strm1 strm2) +@ + if (type_of(strm1) != t_stream || !input_stream_p(strm1)) + cannot_read(strm1); + if (type_of(strm2) != t_stream || !output_stream_p(strm2)) + cannot_write(strm2); + @(return make_echo_stream(strm1, strm2)) +@) + +@(defun make_string_input_stream (strng &o istart iend) + cl_index s, e; +@ + assert_type_string(strng); + if (Null(istart)) + s = 0; + else if (!FIXNUMP(istart) || FIXNUM_MINUSP(istart)) + goto E; + else + s = (cl_index)fix(istart); + if (Null(iend)) + e = strng->string.fillp; + else if (!FIXNUMP(iend) || FIXNUM_MINUSP(iend)) + goto E; + else + e = (cl_index)fix(iend); + if (e > strng->string.fillp || s > e) + goto E; + @(return `make_string_input_stream(strng, s, e)`) + +E: + FEerror("~S and ~S are illegal as :START and :END~%\ +for the string ~S.", + 3, istart, iend, strng); +@) + +@(defun make_string_output_stream () +@ + @(return make_string_output_stream(64)) +@) + +@(defun get_output_stream_string (strm) +@ + if (type_of(strm) != t_stream || + (enum smmode)strm->stream.mode != smm_string_output) + FEerror("~S is not a string-output stream.", 1, strm); + @(return get_output_stream_string(strm)) +@) + +/*---------------------------------------------------------------------- + * (SI:OUTPUT-STREAM-STRING string-output-stream) + * + * extracts the string associated with the given + * string-output-stream. + *---------------------------------------------------------------------- + */ +@(defun si::output_stream_string (strm) +@ + if (type_of(strm) != t_stream || + (enum smmode)strm->stream.mode != smm_string_output) + FEerror("~S is not a string-output stream.", 1, strm); + @(return strm->stream.object0) +@) + +@(defun streamp (strm) +@ + @(return ((type_of(strm) == t_stream) ? Ct : Cnil)) +@) + +@(defun input_stream_p (strm) +@ + assert_type_stream(strm); + @(return (input_stream_p(strm) ? Ct : Cnil)) +@) + +@(defun output_stream_p (strm) +@ + assert_type_stream(strm); + @(return (output_stream_p(strm) ? Ct : Cnil)) +@) + +@(defun stream_element_type (strm) +@ + assert_type_stream(strm); + @(return stream_element_type(strm)) +@) + +@(defun close (strm &key abort) +@ + assert_type_stream(strm); + close_stream(strm, abort != Cnil); + @(return Ct) +@) + +@(defun open (filename + &key (direction Kinput) + (element_type Sbase_char) + (if_exists Cnil iesp) + (if_does_not_exist Cnil idnesp) + &aux strm) + enum smmode smm; +@ + /* INV: open_stream() checks types */ + if (direction == Kinput) { + smm = smm_input; + if (!idnesp) + if_does_not_exist = Kerror; + } else if (direction == Koutput) { + smm = smm_output; + if (!iesp) + if_exists = Knew_version; + if (!idnesp) { + if (if_exists == Koverwrite || + if_exists == Kappend) + if_does_not_exist = Kerror; + else + if_does_not_exist = Kcreate; + } + } else if (direction == Kio) { + smm = smm_io; + if (!iesp) + if_exists = Knew_version; + if (!idnesp) { + if (if_exists == Koverwrite || + if_exists == Kappend) + if_does_not_exist = Kerror; + else + if_does_not_exist = Kcreate; + } + } else if (direction == Kprobe) { + smm = smm_probe; + if (!idnesp) + if_does_not_exist = Cnil; + } else + FEerror("~S is an illegal DIRECTION for OPEN.", + 1, direction); + strm = open_stream(filename, smm, if_exists, if_does_not_exist); + @(return strm) +@) + +@(defun file_position (file_stream &o position) + int i; +@ + assert_type_stream(file_stream); + if (Null(position)) { + i = file_position(file_stream); + if (i < 0) + @(return Cnil) + @(return `MAKE_FIXNUM(i)`) + } else { + if (position == Kstart) + i = 0; + else if (position == Kend) + i = file_length(file_stream); + else if (!FIXNUMP(position) || + (i = fix((position))) < 0) + FEerror("~S is an illegal file position~%\ +for the file-stream ~S.", + 2, position, file_stream); + if (file_position_set(file_stream, i) < 0) + @(return Cnil) + @(return Ct) + } +@) + +@(defun file_length (strm) + int i; +@ + assert_type_stream(strm); + i = file_length(strm); + @(return ((i < 0) ? Cnil : MAKE_FIXNUM(i))) +@) + +@(defun open_stream_p (strm) +@ + assert_type_stream(strm); + /* ANSI and Cltl2 specify that open-stream-p should work + on closed streams, and that a stream is only closed + when #'close has been applied on it */ + @(return (strm->stream.mode != smm_closed ? Ct : Cnil)) +@) + +@(defun si::get_string_input_stream_index (strm) +@ + assert_type_stream(strm); + if ((enum smmode)strm->stream.mode != smm_string_input) + FEerror("~S is not a string-input stream.", 1, strm); + @(return MAKE_FIXNUM(strm->stream.int0)) +@) + +@(defun si::make_string_output_stream_from_string (strng) + cl_object strm; +@ + if (type_of(strng) != t_string || !strng->string.hasfillp) + FEerror("~S is not a string with a fill-pointer.", 1, strng); + strm = alloc_object(t_stream); + strm->stream.mode = (short)smm_string_output; + strm->stream.file = NULL; + strm->stream.object0 = strng; + strm->stream.object1 = OBJNULL; + strm->stream.int0 = strng->string.fillp; + strm->stream.int1 = 0; + @(return strm) +@) + +@(defun si::copy_stream (in out) +@ + assert_type_stream(in); + assert_type_stream(out); + while (!stream_at_end(in)) + writec_stream(readc_stream(in), out); + flush_stream(out); + @(return Ct) +@) + +void +init_file(void) +{ + cl_object standard_input; + cl_object standard_output; + cl_object standard; + cl_object x; + + standard_input = alloc_object(t_stream); + standard_input->stream.mode = (short)smm_input; + standard_input->stream.file = stdin; + standard_input->stream.object0 = Sbase_char; + standard_input->stream.object1 = make_simple_string("stdin"); + standard_input->stream.int0 = 0; + standard_input->stream.int1 = 0; + + standard_output = alloc_object(t_stream); + standard_output->stream.mode = (short)smm_output; + standard_output->stream.file = stdout; + standard_output->stream.object0 = Sbase_char; + standard_output->stream.object1= make_simple_string("stdout"); + standard_output->stream.int0 = 0; + standard_output->stream.int1 = 0; + + terminal_io = standard + = make_two_way_stream(standard_input, standard_output); + register_root(&terminal_io); + + SYM_VAL(Vterminal_io) = standard; + + x = alloc_object(t_stream); + x->stream.mode = (short)smm_synonym; + x->stream.file = NULL; + x->stream.object0 = Vterminal_io; + x->stream.object1 = OBJNULL; + x->stream.int0 = x->stream.int1 = 0; + standard = x; + + SYM_VAL(Vstandard_input) = standard; + SYM_VAL(Vstandard_output) = standard; + SYM_VAL(Verror_output) = standard; + + SYM_VAL(Vquery_io) = standard; + SYM_VAL(Vdebug_io) = standard; + SYM_VAL(Vtrace_output) = standard; + + SYM_VAL(siVignore_eof_on_terminal_io) = Cnil; +} diff --git a/src/c/format.d b/src/c/format.d new file mode 100644 index 000000000..1ed388b18 --- /dev/null +++ b/src/c/format.d @@ -0,0 +1,2089 @@ +/* + format.c -- Format. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include + +cl_object siVindent_formatted_output; + +/******************* WITH CLOS ************************/ +#ifdef CLOS +#define WRITEC_STREAM(c, strm) (*fmt_writec)(c, strm) +#define WRITESTR_STREAM(s, strm) \ + { if (type_of(strm) == t_stream) \ + writestr_stream(s, strm);\ + else {\ + const char* t=s; \ + while (*t != '\0') interactive_writec_stream(*t++, strm); \ + }} +#define FLUSH_STREAM(strm) {\ + if (type_of(strm) == t_stream) flush_stream(strm); \ + else flush_interactive_stream(strm);\ + } +#define FILE_COLUMN(strm) \ + ((type_of(strm) == t_instance) ? -1 : file_column(strm)) +#endif CLOS + +/******************* WITHOUT CLOS *********************/ +#ifndef CLOS +#define WRITEC_STREAM(c, strm) writec_stream(c, strm) +#define WRITESTR_STREAM(s, strm) writestr_stream(s, strm); +#define FLUSH_STREAM(strm) flush_stream(strm) +#define FILE_COLUMN(strm) file_column(strm) +#endif !CLOS + +/******************* WITH THREADS *********************/ +#ifdef THREADS +#define fmt_writec clwp->lwp_fmt_ch_fun +#define fmt_stream clwp->lwp_fmt_stream +#define ctl_origin clwp->lwp_ctl_origin +#define ctl_index clwp->lwp_ctl_index +#define ctl_end clwp->lwp_ctl_end +#define fmt_base clwp->lwp_fmt_base +#define fmt_index clwp->lwp_fmt_index +#define fmt_end clwp->lwp_fmt_end +#define fmt_jmp_buf clwp->lwp_fmt_jmp_buf +#define fmt_indents clwp->lwp_fmt_indents +#define fmt_string clwp->lwp_fmt_string +#define fmt_temporary_stream clwp->lwp_fmt_temporary_stream +#define fmt_temporary_string clwp->lwp_fmt_temporary_string +#define fmt_nparam clwp->lwp_fmt_nparam +#define fmt_param clwp->lwp_fmt_param +#define fmt_spare_spaces clwp->lwp_fmt_spare_spaces +#define fmt_line_length clwp->lwp_fmt_line_length +#endif + +/******************* WITHOUT THREADS ******************/ +#ifndef THREADS +static int (*fmt_writec)(); +static cl_object fmt_stream; +static int ctl_origin; +static int ctl_index; +static int ctl_end; +static cl_object *fmt_base; +static int fmt_index; +static int fmt_end; +static int *fmt_jmp_buf; +static int fmt_indents; +static cl_object fmt_string; +static cl_object fmt_temporary_stream; +static cl_object fmt_temporary_string; +static int fmt_nparam; +struct { + int fmt_param_type; + int fmt_param_value; +} fmt_param[100]; +static int fmt_spare_spaces; +static int fmt_line_length; +#endif !THREADS + +/******************* COMMON ***************************/ + +#define ctl_string (fmt_string->string.self + ctl_origin) + +#define fmt_old volatile cl_object old_fmt_stream; \ + volatile int old_ctl_origin; \ + volatile int old_ctl_index; \ + volatile int old_ctl_end; \ + cl_object * volatile old_fmt_base; \ + volatile int old_fmt_index; \ + volatile int old_fmt_end; \ + int * volatile old_fmt_jmp_buf; \ + volatile int old_fmt_indents; \ + volatile cl_object old_fmt_string +#define fmt_save old_fmt_stream = fmt_stream; \ + old_ctl_origin = ctl_origin; \ + old_ctl_index = ctl_index; \ + old_ctl_end = ctl_end; \ + old_fmt_base = fmt_base; \ + old_fmt_index = fmt_index; \ + old_fmt_end = fmt_end; \ + old_fmt_jmp_buf = fmt_jmp_buf; \ + old_fmt_indents = fmt_indents; \ + old_fmt_string = fmt_string +#define fmt_restore fmt_stream = old_fmt_stream; \ + ctl_origin = old_ctl_origin; \ + ctl_index = old_ctl_index; \ + ctl_end = old_ctl_end; \ + fmt_base = old_fmt_base; \ + fmt_index = old_fmt_index; \ + fmt_end = old_fmt_end; \ + fmt_jmp_buf = old_fmt_jmp_buf; \ + fmt_indents = old_fmt_indents; \ + fmt_string = old_fmt_string +#define fmt_restore1 fmt_stream = old_fmt_stream; \ + ctl_origin = old_ctl_origin; \ + ctl_index = old_ctl_index; \ + ctl_end = old_ctl_end; \ + fmt_jmp_buf = old_fmt_jmp_buf; \ + fmt_indents = old_fmt_indents; \ + fmt_string = old_fmt_string + +#define NONE 0 +#define INT 1 +#define CHAR 2 + +static const char *fmt_big_numeral[] = { + "thousand", + "million", + "billion", + "trillion", + "quadrillion", + "quintillion", + "sextillion", + "septillion", + "octillion" +}; + +static const char *fmt_numeral[] = { + "zero", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", + "ten", "eleven", "twelve", "thirteen", "fourteen", + "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", + "zero", "ten", "twenty", "thirty", "forty", + "fifty", "sixty", "seventy", "eighty", "ninety" +}; + +static const char *fmt_ordinal[] = { + "zeroth", "first", "second", "third", "fourth", + "fifth", "sixth", "seventh", "eighth", "ninth", + "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", + "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", + "zeroth", "tenth", "twentieth", "thirtieth", "fortieth", + "fiftieth", "sixtieth", "seventieth", "eightieth", "ninetieth" +}; + +static void format(cl_object, int, int); + +static void +fmt_error(char *s) +{ + FEerror("Format error: ~A.~%~V@@TV~%\"~A\"~%", + 3, make_simple_string(s), + MAKE_FIXNUM(&ctl_string[ctl_index] - fmt_string->string.self), + fmt_string); +} + +static int +fmt_tempstr(int s) +{ + return(fmt_temporary_string->string.self[s]); +} + +static int +ctl_advance(void) +{ + if (ctl_index >= ctl_end) + fmt_error("unexpected end of control string"); + return(ctl_string[ctl_index++]); +} + +static cl_object +fmt_advance(void) +{ + if (fmt_index >= fmt_end) + fmt_error("arguments exhausted"); + return(fmt_base[fmt_index++]); +} + +static int +fmt_skip(void) +{ + int c, level = 0; + +LOOP: + if (ctl_advance() != '~') + goto LOOP; + for (;;) + switch (c = ctl_advance()) { + case '\'': + ctl_advance(); + + case ',': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '+': + case '-': + case 'v': case 'V': + case '#': + case ':': case '@@': + continue; + + default: + goto DIRECTIVE; + } + +DIRECTIVE: + switch (c) { + case '(': case '[': case '<': case '{': + level++; + break; + + case ')': case ']': case '>': case '}': + if (level == 0) + return(ctl_index); + else + --level; + break; + + case ';': + if (level == 0) + return(ctl_index); + break; + } + goto LOOP; +} + +static void +fmt_max_param(int n) +{ + if (fmt_nparam > n) + fmt_error("too many parameters"); +} + +static void +fmt_not_colon(bool colon) +{ + if (colon) + fmt_error("illegal :"); +} + +static void +fmt_not_atsign(bool atsign) +{ + if (atsign) + fmt_error("illegal @@"); +} + +static void +fmt_not_colon_atsign(bool colon, bool atsign) +{ + if (colon && atsign) + fmt_error("illegal :@@"); +} + +static void +fmt_set_param(int i, int *p, int t, int v) +{ + if (i >= fmt_nparam || fmt_param[i].fmt_param_type == 0) + *p = v; + else if (fmt_param[i].fmt_param_type != t) + fmt_error("illegal parameter type"); + else + *p = fmt_param[i].fmt_param_value; +} + +static void +fmt_set_param_positive(int i, int *p, const char *message) +{ + if (i >= fmt_nparam || fmt_param[i].fmt_param_type == 0) + *p = -1; + else if (fmt_param[i].fmt_param_type != INT) + fmt_error("illegal parameter type"); + else { + *p = fmt_param[i].fmt_param_value; + if (*p < 0) fmt_error(message); + } +} + +static void +fmt_ascii(bool colon, bool atsign) +{ + int mincol, colinc, minpad, padchar; + cl_object x; + int l, i; + + fmt_max_param(4); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &colinc, INT, 1); + fmt_set_param(2, &minpad, INT, 0); + fmt_set_param(3, &padchar, CHAR, ' '); + + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = FILE_COLUMN(fmt_stream); + fmt_temporary_stream->stream.int1 = FILE_COLUMN(fmt_stream); + x = fmt_advance(); + if (colon && Null(x)) + writestr_stream("()", fmt_temporary_stream); + else if (mincol == 0 && minpad == 0) { + princ(x, fmt_stream); + return; + } else + princ(x, fmt_temporary_stream); + l = fmt_temporary_string->string.fillp; + for (i = minpad; l + i < mincol; i += colinc) + ; + if (!atsign) { + write_string(fmt_temporary_string, fmt_stream); + while (i-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + } else { + while (i-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + write_string(fmt_temporary_string, fmt_stream); + } +} + +static void +fmt_S_expression(bool colon, bool atsign) +{ + int mincol, colinc, minpad, padchar; + cl_object x; + int l, i; + + fmt_max_param(4); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &colinc, INT, 1); + fmt_set_param(2, &minpad, INT, 0); + fmt_set_param(3, &padchar, CHAR, ' '); + + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = FILE_COLUMN(fmt_stream); + fmt_temporary_stream->stream.int1 = FILE_COLUMN(fmt_stream); + x = fmt_advance(); + if (colon && Null(x)) + writestr_stream("()", fmt_temporary_stream); + else if (mincol == 0 && minpad == 0) { + prin1(x, fmt_stream); + return; + } else + prin1(x, fmt_temporary_stream); + l = fmt_temporary_string->string.fillp; + for (i = minpad; l + i < mincol; i += colinc) + ; + if (!atsign) { + write_string(fmt_temporary_string, fmt_stream); + while (i-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + } else { + while (i-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + write_string(fmt_temporary_string, fmt_stream); + } +} + + +static void +fmt_integer(cl_object x, bool colon, bool atsign, + int radix, int mincol, int padchar, int commachar) +{ + int l, l1; + int s; + + if (!FIXNUMP(x) && type_of(x) != t_bignum) { + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = FILE_COLUMN(fmt_stream); + fmt_temporary_stream->stream.int1 = FILE_COLUMN(fmt_stream); + setupPRINT(x, fmt_temporary_stream); + PRINTescape = FALSE; + PRINTbase = radix; + write_object(x, 0); + cleanupPRINT(); + l = fmt_temporary_string->string.fillp; + mincol -= l; + while (mincol-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + for (s = 0; l > 0; --l, s++) + WRITEC_STREAM(fmt_tempstr(s), fmt_stream); + return; + } + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = FILE_COLUMN(fmt_stream); + fmt_temporary_stream->stream.int1 = FILE_COLUMN(fmt_stream); + PRINTstream = fmt_temporary_stream; + PRINTradix = FALSE; + PRINTbase = radix; + write_ch_fun = writec_PRINTstream; + write_object(x, 0); + l = l1 = fmt_temporary_string->string.fillp; + s = 0; + if (fmt_tempstr(s) == '-') + --l1; + mincol -= l; + if (colon) + mincol -= (l1 - 1)/3; + if (atsign && fmt_tempstr(s) != '-') + --mincol; + while (mincol-- > 0) + WRITEC_STREAM(padchar, fmt_stream); + if (fmt_tempstr(s) == '-') { + s++; + WRITEC_STREAM('-', fmt_stream); + } else if (atsign) + WRITEC_STREAM('+', fmt_stream); + while (l1-- > 0) { + WRITEC_STREAM(fmt_tempstr(s++), fmt_stream); + if (colon && l1 > 0 && l1%3 == 0) + WRITEC_STREAM(commachar, fmt_stream); + } +} + +static void +fmt_decimal(bool colon, bool atsign) +{ + int mincol, padchar, commachar; + + fmt_max_param(3); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &padchar, CHAR, ' '); + fmt_set_param(2, &commachar, CHAR, ','); + fmt_integer(fmt_advance(), colon, atsign, + 10, mincol, padchar, commachar); +} + +static void +fmt_binary(bool colon, bool atsign) +{ + int mincol, padchar, commachar; + + fmt_max_param(3); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &padchar, CHAR, ' '); + fmt_set_param(2, &commachar, CHAR, ','); + fmt_integer(fmt_advance(), colon, atsign, + 2, mincol, padchar, commachar); +} + +static void +fmt_octal(bool colon, bool atsign) +{ + int mincol, padchar, commachar; + + fmt_max_param(3); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &padchar, CHAR, ' '); + fmt_set_param(2, &commachar, CHAR, ','); + fmt_integer(fmt_advance(), colon, atsign, + 8, mincol, padchar, commachar); +} + +static void +fmt_hexadecimal(bool colon, bool atsign) +{ + int mincol, padchar, commachar; + + fmt_max_param(3); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &padchar, CHAR, ' '); + fmt_set_param(2, &commachar, CHAR, ','); + fmt_integer(fmt_advance(), colon, atsign, + 16, mincol, padchar, commachar); +} + +static void +fmt_write_numeral(int s, int i) +{ + WRITESTR_STREAM(fmt_numeral[fmt_tempstr(s) - '0' + i], fmt_stream) +} + +static void +fmt_write_ordinal(int s, int i) +{ + WRITESTR_STREAM(fmt_ordinal[fmt_tempstr(s) - '0' + i], fmt_stream) +} + +static bool +fmt_thousand(int s, int i, bool b, bool o, int t) +{ + if (i == 3 && fmt_tempstr(s) > '0') { + if (b) + WRITEC_STREAM(' ', fmt_stream); + fmt_write_numeral(s, 0); + WRITESTR_STREAM(" hundred", fmt_stream) + --i; + s++; + b = TRUE; + if (o && (s > t)) + WRITESTR_STREAM("th", fmt_stream) + } + if (i == 3) { + --i; + s++; + } + if (i == 2 && fmt_tempstr(s) > '0') { + if (b) + WRITEC_STREAM(' ', fmt_stream); + if (fmt_tempstr(s) == '1') { + if (o && (s + 2 > t)) + fmt_write_ordinal(++s, 10); + else + fmt_write_numeral(++s, 10); + return(TRUE); + } else { + if (o && (s + 1 > t)) + fmt_write_ordinal(s, 20); + else + fmt_write_numeral(s, 20); + s++; + if (fmt_tempstr(s) > '0') { + WRITEC_STREAM('-', fmt_stream); + if (o && s + 1 > t) + fmt_write_ordinal(s, 0); + else + fmt_write_numeral(s, 0); + } + return(TRUE); + } + } + if (i == 2) + s++; + if (fmt_tempstr(s) > '0') { + if (b) + WRITEC_STREAM(' ', fmt_stream); + if (o && s + 1 > t) + fmt_write_ordinal(s, 0); + else + fmt_write_numeral(s, 0); + return(TRUE); + } + return(b); +} + +static bool +fmt_nonillion(int s, int i, bool b, bool o, int t) +{ + int j; + + for (; i > 3; i -= j) { + b = fmt_thousand(s, j = (i+2)%3+1, b, FALSE, t); + if (j != 3 || fmt_tempstr(s) != '0' || + fmt_tempstr(s+1) != '0' || fmt_tempstr(s+2) != '0') { + WRITEC_STREAM(' ', fmt_stream); + WRITESTR_STREAM(fmt_big_numeral[(i - 1)/3 - 1], + fmt_stream) + s += j; + if (o && s > t) + WRITESTR_STREAM("th", fmt_stream) + } else + s += j; + } + return(fmt_thousand(s, i, b, o, t)); +} + +static void +fmt_roman(int i, int one, int five, int ten, bool colon) +{ + int j; + + if (i == 0) + return; + if ((!colon && i < 4) || (colon && i < 5)) + for (j = 0; j < i; j++) + WRITEC_STREAM(one, fmt_stream); + else if (!colon && i == 4) { + WRITEC_STREAM(one, fmt_stream); + WRITEC_STREAM(five, fmt_stream); + } else if ((!colon && i < 9) || colon) { + WRITEC_STREAM(five, fmt_stream); + for (j = 5; j < i; j++) + WRITEC_STREAM(one, fmt_stream); + } else if (!colon && i == 9) { + WRITEC_STREAM(one, fmt_stream); + WRITEC_STREAM(ten, fmt_stream); + } +} + +static void +fmt_radix(bool colon, bool atsign) +{ + int radix, mincol, padchar, commachar; + cl_object x; + int i, j, k; + int s, t; + bool b; + + if (fmt_nparam == 0) { + x = fmt_advance(); + assert_type_integer(x); + if (atsign) { + if (FIXNUMP(x)) + i = fix(x); + else + i = -1; + if ((!colon && (i <= 0 || i >= 4000)) || + (colon && (i <= 0 || i >= 5000))) { + fmt_integer(x, FALSE, FALSE, 10, 0, ' ', ','); + return; + } + fmt_roman(i/1000, 'M', '*', '*', colon); + fmt_roman(i%1000/100, 'C', 'D', 'M', colon); + fmt_roman(i%100/10, 'X', 'L', 'C', colon); + fmt_roman(i%10, 'I', 'V', 'X', colon); + return; + } + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = FILE_COLUMN(fmt_stream); + fmt_temporary_stream->stream.int1 = FILE_COLUMN(fmt_stream); + PRINTstream = fmt_temporary_stream; + PRINTradix = FALSE; + PRINTbase = 10; + write_ch_fun = writec_PRINTstream; + write_object(x, 0); + s = 0; + i = fmt_temporary_string->string.fillp; + if (i == 1 && fmt_tempstr(s) == '0') { + WRITESTR_STREAM("zero", fmt_stream) + if (colon) + WRITESTR_STREAM("th", fmt_stream) + return; + } else if (fmt_tempstr(s) == '-') { + WRITESTR_STREAM("minus ", fmt_stream) + --i; + s++; + } + t = fmt_temporary_string->string.fillp; + for (; fmt_tempstr(--t) == '0' ;) ; + for (b = FALSE; i > 0; i -= j) { + b = fmt_nonillion(s, j = (i+29)%30+1, b, + i<=30&&colon, t); + s += j; + if (b && i > 30) { + for (k = (i - 1)/30; k > 0; --k) + WRITESTR_STREAM(" nonillion", + fmt_stream) + if (colon && s > t) + WRITESTR_STREAM("th", fmt_stream) + } + } + return; + } + fmt_max_param(4); + fmt_set_param(0, &radix, INT, 10); + fmt_set_param(1, &mincol, INT, 0); + fmt_set_param(2, &padchar, CHAR, ' '); + fmt_set_param(3, &commachar, CHAR, ','); + x = fmt_advance(); + assert_type_integer(x); + if (radix < 0 || radix > 36) + FEerror("~D is illegal as a radix.", 1, MAKE_FIXNUM(radix)); + fmt_integer(x, colon, atsign, radix, mincol, padchar, commachar); +} + +static void +fmt_plural(bool colon, bool atsign) +{ + fmt_max_param(0); + if (colon) { + if (fmt_index == 0) + fmt_error("can't back up"); + --fmt_index; + } + if (eql(fmt_advance(), MAKE_FIXNUM(1))) { + if (atsign) + WRITEC_STREAM('y', fmt_stream); + } + else + if (atsign) + WRITESTR_STREAM("ies", fmt_stream) + else + WRITEC_STREAM('s', fmt_stream); +} + +static void +fmt_character(bool colon, bool atsign) +{ + cl_object x; + cl_index i; + + fmt_max_param(0); + fmt_temporary_string->string.fillp = 0; + fmt_temporary_stream->stream.int0 = 0; + fmt_temporary_stream->stream.int1 = 0; + x = fmt_advance(); + assert_type_character(x); + prin1(x, fmt_temporary_stream); + if (!colon && atsign) + i = 0; + else + i = 2; + for (; i < fmt_temporary_string->string.fillp; i++) + WRITEC_STREAM(fmt_tempstr(i), fmt_stream); +} + +static void +fmt_fix_float(bool colon, bool atsign) +{ + int w, d, k, overflowchar, padchar; + double f; + int sign; + char buff[256], *b, buff1[256]; + int exp; + int i, j; + cl_object x; + int n, m; + + b = buff1 + 1; + + fmt_not_colon(colon); + fmt_max_param(5); + fmt_set_param_positive(0, &w, "illegal width"); + fmt_set_param_positive(1, &d, "illegal number of digits"); + fmt_set_param(2, &k, INT, 0); + fmt_set_param(3, &overflowchar, CHAR, -1); + fmt_set_param(4, &padchar, CHAR, ' '); + + x = fmt_advance(); + if (FIXNUMP(x) || + type_of(x) == t_bignum || + type_of(x) == t_ratio) + x = make_shortfloat(object_to_float(x)); + if (!REAL_TYPE(type_of(x))) { + if (fmt_nparam > 1) fmt_nparam = 1; + --fmt_index; + fmt_decimal(colon, atsign); + return; + } + if (type_of(x) == t_longfloat) + n = 16; + else + n = 7; + f = number_to_double(x); + edit_double(n, f, &sign, buff, &exp); + if (exp + k > 100 || exp + k < -100 || d > 100) { + prin1(x, fmt_stream); + return; + } + if (d >= 0) + m = d + exp + k + 1; + else if (w >= 0) { + if (exp + k >= 0) + m = w - 1; + else + m = w + exp + k - 2; + if (sign < 0 || atsign) + --m; + if (m == 0) + m = 1; + } else + m = n; + if (m <= 0) { + if (m == 0 && buff[0] >= '5') { + exp++; + n = m = 1; + buff[0] = '1'; + } else + n = m = 0; + } else if (m < n) { + n = m; + edit_double(n, f, &sign, buff, &exp); + } + while (n >= 0) + if (buff[n - 1] == '0') + --n; + else + break; + exp += k; + j = 0; + if (exp >= 0) { + for (i = 0; i <= exp; i++) + b[j++] = i < n ? buff[i] : '0'; + b[j++] = '.'; + if (d >= 0) + for (m = i + d; i < m; i++) + b[j++] = i < n ? buff[i] : '0'; + else + for (; i < n; i++) + b[j++] = buff[i]; + } else { + b[j++] = '.'; + if (d >= 0) { + for (i = 0; i < (-exp) - 1 && i < d; i++) + b[j++] = '0'; + for (m = d - i, i = 0; i < m; i++) + b[j++] = i < n ? buff[i] : '0'; + } else if (n > 0) { + for (i = 0; i < (-exp) - 1; i++) + b[j++] = '0'; + for (i = 0; i < n; i++) + b[j++] = buff[i]; + } + } + b[j] = '\0'; + if (w >= 0) { + if (sign < 0 || atsign) + --w; + if (j > w && overflowchar >= 0) { + fmt_set_param(0, &w, INT, 0); + for (i = 0; i < w; i++) + WRITEC_STREAM(overflowchar, fmt_stream); + return; + } + if (j < w && b[j-1] == '.') { + b[j++] = '0'; + b[j] = '\0'; + } + if (j < w && b[0] == '.') { + *--b = '0'; + j++; + } + for (i = j; i < w; i++) + WRITEC_STREAM(padchar, fmt_stream); + } else { + if (b[0] == '.') { + *--b = '0'; + j++; + } + if (d < 0 && b[j-1] == '.') { + b[j++] = '0'; + b[j] = '\0'; + } + } + if (sign < 0) + WRITEC_STREAM('-', fmt_stream); + else if (atsign) + WRITEC_STREAM('+', fmt_stream); + WRITESTR_STREAM(b, fmt_stream) +} + +static int +fmt_exponent_length(int e) +{ + int i; + + if (e == 0) + return(1); + if (e < 0) + e = -e; + for (i = 0; e > 0; i++, e /= 10) + ; + return(i); +} + +static void +fmt_exponent1(int e) +{ + if (e == 0) + return; + fmt_exponent1(e/10); + WRITEC_STREAM('0' + e%10, fmt_stream); +} + +static void +fmt_exponent(int e) +{ + if (e == 0) { + WRITEC_STREAM('0', fmt_stream); + return; + } + if (e < 0) + e = -e; + fmt_exponent1(e); +} + +static void +fmt_exponential_float(bool colon, bool atsign) +{ + int w, d, e, k, overflowchar, padchar, exponentchar; + double f; + int sign; + char buff[256], *b, buff1[256]; + int exp; + int i, j; + cl_object x, y; + int n, m; + enum type t; + + b = buff1 + 1; + + fmt_not_colon(colon); + fmt_max_param(7); + fmt_set_param_positive(0, &w, "illegal width"); + fmt_set_param_positive(1, &d, "illegal number of digits"); + fmt_set_param_positive(2, &e, "illegal number of digits in exponent"); + fmt_set_param(3, &k, INT, 1); + fmt_set_param(4, &overflowchar, CHAR, -1); + fmt_set_param(5, &padchar, CHAR, ' '); + fmt_set_param(6, &exponentchar, CHAR, -1); + + x = fmt_advance(); + if (FIXNUMP(x) || + type_of(x) == t_bignum || + type_of(x) == t_ratio) + x = make_shortfloat(object_to_float(x)); + if (!REAL_TYPE(type_of(x))) { + if (fmt_nparam > 1) fmt_nparam = 1; + --fmt_index; + fmt_decimal(colon, atsign); + return; + } + if (type_of(x) == t_longfloat) + n = 16; + else + n = 7; + f = number_to_double(x); + edit_double(n, f, &sign, buff, &exp); + if (d >= 0) { + if (k > 0) { + if (!(k < d + 2)) + fmt_error("illegal scale factor"); + m = d + 1; + } else { + if (!(k > -d)) + fmt_error("illegal scale factor"); + m = d + k; + } + } else if (w >= 0) { + if (k > 0) + m = w - 1; + else + m = w + k - 1; + if (sign < 0 || atsign) + --m; + if (e >= 0) + m -= e + 2; + else + m -= fmt_exponent_length(e - k + 1) + 2; + } else + m = n; + if (m <= 0) { + if (m == 0 && buff[0] >= '5') { + exp++; + n = m = 1; + buff[0] = '1'; + } else + n = m = 0; + } else if (m < n) { + n = m; + edit_double(n, f, &sign, buff, &exp); + } + while (n >= 0) + if (buff[n - 1] == '0') + --n; + else + break; + exp = exp - k + 1; + j = 0; + if (k > 0) { + for (i = 0; i < k; i++) + b[j++] = i < n ? buff[i] : '0'; + b[j++] = '.'; + if (d >= 0) + for (m = i + (d - k + 1); i < m; i++) + b[j++] = i < n ? buff[i] : '0'; + else + for (; i < n; i++) + b[j++] = buff[i]; + } else { + b[j++] = '.'; + if (d >= 0) { + for (i = 0; i < -k && i < d; i++) + b[j++] = '0'; + for (m = d - i, i = 0; i < m; i++) + b[j++] = i < n ? buff[i] : '0'; + } else if (n > 0) { + for (i = 0; i < -k; i++) + b[j++] = '0'; + for (i = 0; i < n; i++) + b[j++] = buff[i]; + } + } + b[j] = '\0'; + if (w >= 0) { + if (sign < 0 || atsign) + --w; + i = fmt_exponent_length(exp); + if (e >= 0) { + if (i > e) { + if (overflowchar >= 0) + goto OVER; + else + e = i; + } + w -= e + 2; + } else + w -= i + 2; + if (j > w && overflowchar >= 0) + goto OVER; + if (j < w && b[j-1] == '.') { + b[j++] = '0'; + b[j] = '\0'; + } + if (j < w && b[0] == '.') { + *--b = '0'; + j++; + } + for (i = j; i < w; i++) + WRITEC_STREAM(padchar, fmt_stream); + } else { + if (b[j-1] == '.') { + b[j++] = '0'; + b[j] = '\0'; + } + if (d < 0 && b[0] == '.') { + *--b = '0'; + j++; + } + } + if (sign < 0) + WRITEC_STREAM('-', fmt_stream); + else if (atsign) + WRITEC_STREAM('+', fmt_stream); + WRITESTR_STREAM(b, fmt_stream) + y = symbol_value(Vread_default_float_format); + if (exponentchar < 0) { + if (y == Slong_float || y == Sdouble_float) + t = t_longfloat; + else + t = t_shortfloat; + if (type_of(x) == t) + exponentchar = 'E'; + else if (type_of(x) == t_shortfloat) + exponentchar = 'S'; + else + exponentchar = 'L'; + } + WRITEC_STREAM(exponentchar, fmt_stream); + if (exp < 0) + WRITEC_STREAM('-', fmt_stream); + else + WRITEC_STREAM('+', fmt_stream); + if (e >= 0) + for (i = e - fmt_exponent_length(exp); i > 0; --i) + WRITEC_STREAM('0', fmt_stream); + fmt_exponent(exp); + return; + +OVER: + fmt_set_param(0, &w, INT, -1); + for (i = 0; i < w; i++) + WRITEC_STREAM(overflowchar, fmt_stream); + return; +} + +static void +fmt_general_float(bool colon, bool atsign) +{ + int w, d, e, k, overflowchar, padchar, exponentchar; + int sign, exp; + char buff[256]; + cl_object x; + int n, ee, ww, q, dd; + + fmt_not_colon(colon); + fmt_max_param(7); + fmt_set_param_positive(0, &w, "illegal width"); + fmt_set_param_positive(1, &d, "illegal number of digits"); + fmt_set_param_positive(2, &e, "illegal number of digits in exponent"); + fmt_set_param(3, &k, INT, 1); + fmt_set_param(4, &overflowchar, CHAR, -1); + fmt_set_param(5, &padchar, CHAR, ' '); + fmt_set_param(6, &exponentchar, CHAR, -1); + + x = fmt_advance(); + if (!REAL_TYPE(type_of(x))) { + if (fmt_nparam > 1) fmt_nparam = 1; + --fmt_index; + fmt_decimal(colon, atsign); + return; + } + if (type_of(x) == t_longfloat) + q = 16; + else + q = 7; + edit_double(q, number_to_double(x), &sign, buff, &exp); + n = exp + 1; + while (q >= 0) + if (buff[q - 1] == '0') + --q; + else + break; + if (e >= 0) + ee = e + 2; + else + ee = 4; + ww = w - ee; + if (d < 0) { + d = n < 7 ? n : 7; + d = q > d ? q : d; + } + dd = d - n; + if (0 <= dd && dd <= d) { + fmt_nparam = 5; + fmt_param[0].fmt_param_value = ww; + fmt_param[1].fmt_param_value = dd; + fmt_param[1].fmt_param_type = INT; + fmt_param[2].fmt_param_type = NONE; + fmt_param[3] = fmt_param[4]; + fmt_param[4] = fmt_param[5]; + --fmt_index; + fmt_fix_float(colon, atsign); + if (w >= 0) + while (ww++ < w) + WRITEC_STREAM(padchar, fmt_stream); + return; + } + fmt_param[1].fmt_param_value = d; + fmt_param[1].fmt_param_type = INT; + --fmt_index; + fmt_exponential_float(colon, atsign); +} + +static void +fmt_dollars_float(bool colon, bool atsign) +{ + int d, n, w, padchar; + double f; + int sign; + char buff[256]; + int exp; + int q, i; + cl_object x; + + fmt_max_param(4); + fmt_set_param(0, &d, INT, 2); + if (d < 0) + fmt_error("illegal number of digits"); + fmt_set_param(1, &n, INT, 1); + if (n < 0) + fmt_error("illegal number of digits"); + fmt_set_param(2, &w, INT, 0); + if (w < 0) + fmt_error("illegal width"); + fmt_set_param(3, &padchar, CHAR, ' '); + x = fmt_advance(); + if (!REAL_TYPE(type_of(x))) { + if (fmt_nparam < 3) + fmt_nparam = 0; + else { + fmt_nparam = 1; + fmt_param[0] = fmt_param[2]; + } + --fmt_index; + fmt_decimal(colon, atsign); + return; + } + q = 7; + if (type_of(x) == t_longfloat) + q = 16; + f = number_to_double(x); + edit_double(q, f, &sign, buff, &exp); + if ((q = exp + d + 1) > 0) + edit_double(q, f, &sign, buff, &exp); + exp++; + if (w > 100 || exp > 100 || exp < -100) { + fmt_nparam = 6; + fmt_param[0] = fmt_param[2]; + fmt_param[1].fmt_param_value = d + n - 1; + fmt_param[1].fmt_param_type = INT; + fmt_param[2].fmt_param_type = + fmt_param[3].fmt_param_type = + fmt_param[4].fmt_param_type = NONE; + fmt_param[5] = fmt_param[3]; + --fmt_index; + fmt_exponential_float(colon, atsign); + } + if (exp > n) + n = exp; + if (sign < 0 || atsign) + --w; + if (colon) { + if (sign < 0) + WRITEC_STREAM('-', fmt_stream); + else if (atsign) + WRITEC_STREAM('+', fmt_stream); + while (--w > n + d) + WRITEC_STREAM(padchar, fmt_stream); + } else { + while (--w > n + d) + WRITEC_STREAM(padchar, fmt_stream); + if (sign < 0) + WRITEC_STREAM('-', fmt_stream); + else if (atsign) + WRITEC_STREAM('+', fmt_stream); + } + for (i = n - exp; i > 0; --i) + WRITEC_STREAM('0', fmt_stream); + for (i = 0; i < exp; i++) + WRITEC_STREAM((i < q ? buff[i] : '0'), fmt_stream); + WRITEC_STREAM('.', fmt_stream); + for (d += i; i < d; i++) + WRITEC_STREAM((i < q ? buff[i] : '0'), fmt_stream); +} + +static void +fmt_percent(bool colon, bool atsign) +{ + int n, i; + + fmt_max_param(1); + fmt_set_param(0, &n, INT, 1); + fmt_not_colon(colon); + fmt_not_atsign(atsign); + while (n-- > 0) { + WRITEC_STREAM('\n', fmt_stream); + if (n == 0) + for (i = fmt_indents; i > 0; --i) + WRITEC_STREAM(' ', fmt_stream); + } +} + +static void +fmt_ampersand(bool colon, bool atsign) +{ + int n; + + fmt_max_param(1); + fmt_set_param(0, &n, INT, 1); + fmt_not_colon(colon); + fmt_not_atsign(atsign); + if (n == 0) + return; + if (FILE_COLUMN(fmt_stream) != 0) + WRITEC_STREAM('\n', fmt_stream); + while (--n > 0) + WRITEC_STREAM('\n', fmt_stream); + fmt_indents = 0; +} + +static void +fmt_bar(bool colon, bool atsign) +{ + int n; + + fmt_max_param(1); + fmt_set_param(0, &n, INT, 1); + fmt_not_colon(colon); + fmt_not_atsign(atsign); + while (n-- > 0) + WRITEC_STREAM('\f', fmt_stream); +} + +static void +fmt_tilde(bool colon, bool atsign) +{ + int n; + + fmt_max_param(1); + fmt_set_param(0, &n, INT, 1); + fmt_not_colon(colon); + fmt_not_atsign(atsign); + while (n-- > 0) + WRITEC_STREAM('~', fmt_stream); +} + +static void +fmt_newline(bool colon, bool atsign) +{ + fmt_max_param(0); + fmt_not_colon_atsign(colon, atsign); + if (atsign) + WRITEC_STREAM('\n', fmt_stream); + while (ctl_index < ctl_end && isspace(ctl_string[ctl_index])) { + if (colon) + WRITEC_STREAM(ctl_string[ctl_index], fmt_stream); + ctl_index++; + } +} + +static void +fmt_tabulate(bool colon, bool atsign) +{ + int colnum, colinc; + int c, i; + + fmt_max_param(2); + fmt_not_colon(colon); + fmt_set_param(0, &colnum, INT, 1); + fmt_set_param(1, &colinc, INT, 1); + if (!atsign) { + c = FILE_COLUMN(fmt_stream); + if (c < 0) { + WRITESTR_STREAM(" ", fmt_stream) + return; + } + if (c > colnum && colinc <= 0) + return; + while (c > colnum) + colnum += colinc; + for (i = colnum - c; i > 0; --i) + WRITEC_STREAM(' ', fmt_stream); + } else { + for (i = colnum; i > 0; --i) + WRITEC_STREAM(' ', fmt_stream); + c = FILE_COLUMN(fmt_stream); + if (c < 0 || colinc <= 0) + return; + colnum = 0; + while (c > colnum) + colnum += colinc; + for (i = colnum - c; i > 0; --i) + WRITEC_STREAM(' ', fmt_stream); + } +} + +static void +fmt_asterisk(bool colon, bool atsign) +{ + int n; + + fmt_max_param(1); + fmt_not_colon_atsign(colon, atsign); + if (atsign) { + fmt_set_param(0, &n, INT, 0); + if (n < 0 || n >= fmt_end) + fmt_error("can't goto"); + fmt_index = n; + } else if (colon) { + fmt_set_param(0, &n, INT, 1); + if (n > fmt_index) + fmt_error("can't back up"); + fmt_index -= n; + } else { + fmt_set_param(0, &n, INT, 1); + while (n-- > 0) + fmt_advance(); + } +} + +static void +fmt_indirection(bool colon, bool atsign) +{ + cl_object s, l; + fmt_old; + jmp_buf fmt_jmp_buf0; + int up_colon; + + fmt_max_param(0); + fmt_not_colon(colon); + s = fmt_advance(); + if (type_of(s) != t_string) + fmt_error("control string expected"); + if (atsign) { + fmt_save; + fmt_jmp_buf = (int *)fmt_jmp_buf0; + fmt_string = s; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + if (--up_colon) + fmt_error("illegal ~:^"); + } else + format(fmt_stream, 0, s->string.fillp); + fmt_restore1; + } else { + l = fmt_advance(); + fmt_save; + fmt_base = alloca(length(l) * sizeof(cl_object)); + fmt_index = 0; + for (fmt_end = 0; !endp(l); fmt_end++, l = CDR(l)) + fmt_base[fmt_end] = CAR(l); + fmt_jmp_buf = (int *)fmt_jmp_buf0; + fmt_string = s; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + if (--up_colon) + fmt_error("illegal ~:^"); + } else + format(fmt_stream, 0, s->string.fillp); + fmt_restore; + } +} + +static void +fmt_case(bool colon, bool atsign) +{ + cl_object x; + cl_index i; + int j; + fmt_old; + jmp_buf fmt_jmp_buf0; + int up_colon; + bool b; + + x = make_string_output_stream(64); + i = ctl_index; + j = fmt_skip(); + if (ctl_string[--j] != ')' || ctl_string[--j] != '~') + fmt_error("~) expected"); + fmt_save; + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) + ; + else + format(x, ctl_origin + i, j - i); + fmt_restore1; + x = x->stream.object0; + if (!colon && !atsign) + for (i = 0; i < x->string.fillp; i++) { + if (isupper(j = x->string.self[i])) + j = tolower(j); + WRITEC_STREAM(j, fmt_stream); + } + else if (colon && !atsign) + for (b = TRUE, i = 0; i < x->string.fillp; i++) { + if (islower(j = x->string.self[i])) { + if (b) + j = toupper(j); + b = FALSE; + } else if (isupper(j)) { + if (!b) + j = tolower(j); + b = FALSE; + } else if (!isdigit(j)) + b = TRUE; + WRITEC_STREAM(j, fmt_stream); + } + else if (!colon && atsign) + for (b = TRUE, i = 0; i < x->string.fillp; i++) { + if (islower(j = x->string.self[i])) { + if (b) + j = toupper(j); + b = FALSE; + } else if (isupper(j)) { + if (!b) + j = tolower(j); + b = FALSE; + } + WRITEC_STREAM(j, fmt_stream); + } + else + for (i = 0; i < x->string.fillp; i++) { + if (islower(j = x->string.self[i])) + j = toupper(j); + WRITEC_STREAM(j, fmt_stream); + } + if (up_colon) + ecls_longjmp(fmt_jmp_buf, up_colon); +} + +static void +fmt_conditional(bool colon, bool atsign) +{ + int i, j, k; + cl_object x; + int n; + bool done; + fmt_old; + + fmt_not_colon_atsign(colon, atsign); + if (colon) { + fmt_max_param(0); + i = ctl_index; + j = fmt_skip(); + if (ctl_string[--j] != ';' || ctl_string[--j] != '~') + fmt_error("~; expected"); + k = fmt_skip(); + if (ctl_string[--k] != ']' || ctl_string[--k] != '~') + fmt_error("~] expected"); + if (Null(fmt_advance())) { + fmt_save; + format(fmt_stream, ctl_origin + i, j - i); + fmt_restore1; + } else { + fmt_save; + format(fmt_stream, ctl_origin + j + 2, k - (j + 2)); + fmt_restore1; + } + } else if (atsign) { + i = ctl_index; + j = fmt_skip(); + if (ctl_string[--j] != ']' || ctl_string[--j] != '~') + fmt_error("~] expected"); + if (Null(fmt_advance())) + ; + else { + --fmt_index; + fmt_save; + format(fmt_stream, ctl_origin + i, j - i); + fmt_restore1; + } + } else { + fmt_max_param(1); + if (fmt_nparam == 0) { + x = fmt_advance(); + if (!FIXNUMP(x)) + fmt_error("illegal argument for conditional"); + n = fix(x); + } else + fmt_set_param(0, &n, INT, 0); + i = ctl_index; + for (done = FALSE;; --n) { + j = fmt_skip(); + for (k = j; ctl_string[--k] != '~';) + ; + if (n == 0) { + fmt_save; + format(fmt_stream, ctl_origin + i, k - i); + fmt_restore1; + done = TRUE; + } + i = j; + if (ctl_string[--j] == ']') { + if (ctl_string[--j] != '~') + fmt_error("~] expected"); + return; + } + if (ctl_string[j] == ';') { + if (ctl_string[--j] == '~') + continue; + if (ctl_string[j] == ':') + goto ELSE; + } + fmt_error("~; or ~] expected"); + } + ELSE: + if (ctl_string[--j] != '~') + fmt_error("~:; expected"); + j = fmt_skip(); + if (ctl_string[--j] != ']' || ctl_string[--j] != '~') + fmt_error("~] expected"); + if (!done) { + fmt_save; + format(fmt_stream, ctl_origin + i, j - i); + fmt_restore1; + } + } +} + +static void +fmt_iteration(bool colon, bool atsign) +{ + int n, i, o; + volatile int j; + bool colon_close = FALSE; + cl_object l; + fmt_old; + jmp_buf fmt_jmp_buf0; + int up_colon; + + fmt_max_param(1); + fmt_set_param(0, &n, INT, 1000000); + i = ctl_index; + j = fmt_skip(); + if (ctl_string[--j] != '}') + fmt_error("~} expected"); + if (ctl_string[--j] == ':') { + colon_close = TRUE; + --j; + } + if (ctl_string[j] != '~') + fmt_error("syntax error"); + o = ctl_origin; + if (!colon && !atsign) { + l = fmt_advance(); + fmt_save; + fmt_base = (cl_object *)alloca(length(l) * sizeof(cl_object)); + fmt_index = 0; + for (fmt_end = 0; !endp(l); fmt_end++, l = CDR(l)) + fmt_base[fmt_end] = CAR(l); + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if (colon_close) + goto L1; + while (fmt_index < fmt_end) { + L1: + if (n-- <= 0) + break; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + if (--up_colon) + fmt_error("illegal ~:^"); + break; + } + format(fmt_stream, o + i, j - i); + } + fmt_restore; + } else if (colon && !atsign) { + int fl = 0; + volatile cl_object l0; + l0 = fmt_advance(); + fmt_save; + for (l = l0; !endp(l); l = CDR(l)) + fl += length(CAR(l)); + fmt_base = (cl_object *)alloca(fl * sizeof(cl_object)); + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if (colon_close) + goto L2; + while (!endp(l0)) { + L2: + if (n-- <= 0) + break; + l = CAR(l0); + l0 = CDR(l0); + fmt_index = 0; + for (fmt_end = 0; !endp(l); fmt_end++, l = CDR(l)) + fmt_base[fmt_end] = CAR(l); + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + if (--up_colon) + break; + else + continue; + } + format(fmt_stream, o + i, j - i); + } + fmt_restore; + } else if (!colon && atsign) { + fmt_save; + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if (colon_close) + goto L3; + while (fmt_index < fmt_end) { + L3: + if (n-- <= 0) + break; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + if (--up_colon) + fmt_error("illegal ~:^"); + break; + } + format(fmt_stream, o + i, j - i); + } + fmt_restore1; + } else if (colon && atsign) { + if (colon_close) + goto L4; + while (fmt_index < fmt_end) { + L4: + if (n-- <= 0) + break; + l = fmt_advance(); + fmt_save; + fmt_base = (cl_object *)alloca(length(l) * sizeof(cl_object)); + fmt_index = 0; + for (fmt_end = 0; !endp(l); fmt_end++, l = CDR(l)) + fmt_base[fmt_end] = CAR(l); + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + fmt_restore; + if (--up_colon) + break; + else + continue; + } + format(fmt_stream, o + i, j - i); + fmt_restore; + } + } +} + +static void +fmt_justification(volatile bool colon, bool atsign) +{ + int mincol, colinc, minpad, padchar; + cl_object fields[16]; + fmt_old; + jmp_buf fmt_jmp_buf0; + volatile int i, j, k, l, m, n, j0, l0; + int up_colon; + volatile int special = 0; + volatile int spare_spaces, line_length; + + fmt_max_param(4); + fmt_set_param(0, &mincol, INT, 0); + fmt_set_param(1, &colinc, INT, 1); + fmt_set_param(2, &minpad, INT, 0); + fmt_set_param(3, &padchar, CHAR, ' '); + + n = 0; + for (;;) { + if (n >= 16) + fmt_error("too many fields"); + i = ctl_index; + j0 = j = fmt_skip(); + while (ctl_string[--j] != '~') + ; + fields[n] = make_string_output_stream(64); + fmt_save; + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if ((up_colon = ecls_setjmp(fmt_jmp_buf))) { + --n; + if (--up_colon) + fmt_error("illegal ~:^"); + fmt_restore1; + while (ctl_string[--j0] != '>') + j0 = fmt_skip(); + if (ctl_string[--j0] != '~') + fmt_error("~> expected"); + break; + } + format(fields[n++], ctl_origin + i, j - i); + fmt_restore1; + if (ctl_string[--j0] == '>') { + if (ctl_string[--j0] != '~') + fmt_error("~> expected"); + break; + } else if (ctl_string[j0] != ';') + fmt_error("~; expected"); + else if (ctl_string[--j0] == ':') { + if (n != 1) + fmt_error("illegal ~:;"); + special = 1; + for (j = j0; ctl_string[j] != '~'; --j) + ; + fmt_save; + format(fmt_stream, ctl_origin + j, j0 - j + 2); + fmt_restore1; + spare_spaces = fmt_spare_spaces; + line_length = fmt_line_length; + } else if (ctl_string[j0] != '~') + fmt_error("~; expected"); + } + for (i = special, l = 0; i < n; i++) + l += fields[i]->stream.object0->string.fillp; + m = n - 1 - special; + if (m <= 0 && !colon && !atsign) { + m = 0; + colon = TRUE; + } + if (colon) + m++; + if (atsign) + m++; + l0 = l; + l += minpad * m; + for (k = 0; mincol + k * colinc < l; k++) + ; + l = mincol + k * colinc; + if (special != 0 && + FILE_COLUMN(fmt_stream) + l + spare_spaces >= line_length) + princ(fields[0]->stream.object0, fmt_stream); + l -= l0; + for (i = special; i < n; i++) { + if (i > 0 || colon) + for (j = l / m, l -= j, --m; j > 0; --j) + WRITEC_STREAM(padchar, fmt_stream); + princ(fields[i]->stream.object0, fmt_stream); + } + if (atsign) + for (j = l; j > 0; --j) + WRITEC_STREAM(padchar, fmt_stream); +} + +static void +fmt_up_and_out(bool colon, bool atsign) +{ + int i, j, k; + + fmt_max_param(3); + fmt_not_atsign(atsign); + if (fmt_nparam == 0) { + if (fmt_index >= fmt_end) + ecls_longjmp(fmt_jmp_buf, ++colon); + } else if (fmt_nparam == 1) { + fmt_set_param(0, &i, INT, 0); + if (i == 0) + ecls_longjmp(fmt_jmp_buf, ++colon); + } else if (fmt_nparam == 2) { + fmt_set_param(0, &i, INT, 0); + fmt_set_param(1, &j, INT, 0); + if (i == j) + ecls_longjmp(fmt_jmp_buf, ++colon); + } else { + fmt_set_param(0, &i, INT, 0); + fmt_set_param(1, &j, INT, 0); + fmt_set_param(2, &k, INT, 0); + if (i <= j && j <= k) + ecls_longjmp(fmt_jmp_buf, ++colon); + } +} + +static void +fmt_semicolon(bool colon, bool atsign) +{ + fmt_not_atsign(atsign); + if (!colon) + fmt_error("~:; expected"); + fmt_max_param(2); + fmt_set_param(0, &fmt_spare_spaces, INT, 0); + fmt_set_param(1, &fmt_line_length, INT, 72); +} + +@(defun format (strm string &rest args) + cl_object x = OBJNULL; + jmp_buf fmt_jmp_buf0; + bool colon; + fmt_old; +@ + if (Null(strm)) { + strm = make_string_output_stream(64); + x = strm->stream.object0; + } else if (strm == Ct) + strm = symbol_value(Vstandard_output); + else if (type_of(strm) == t_string) { + x = strm; + if (!x->string.hasfillp) + FEerror("The string ~S doesn't have a fill-pointer.", 1, x); + strm = make_string_output_stream(0); + strm->stream.object0 = x; + x = OBJNULL; + } + fmt_save; +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + fmt_writec = writec_stream; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + fmt_writec = interactive_writec_stream; + else +#endif CLOS + FEerror("~S is not a stream.", 1, strm); + assert_type_string(string); + if (frs_push(FRS_PROTECT, Cnil)) { + frs_pop(); + fmt_restore; + unwind(nlj_fr, nlj_tag); + } + fmt_base = (cl_object *)args; + fmt_index = 0; + fmt_end = narg - 2; + fmt_jmp_buf = (int *)fmt_jmp_buf0; + if (symbol_value(siVindent_formatted_output) != Cnil) + fmt_indents = FILE_COLUMN(strm); + else + fmt_indents = 0; + fmt_string = string; + if ((colon = ecls_setjmp(fmt_jmp_buf))) { + if (--colon) + fmt_error("illegal ~:^"); + } else { + format(strm, 0, string->string.fillp); + FLUSH_STREAM(strm); + } + frs_pop(); + fmt_restore; + @(return (x == OBJNULL? Cnil : x)) +@) + +static void +format(cl_object fmt_stream0, int ctl_origin0, int ctl_end0) +{ + int c, i, n; + bool colon, atsign; + cl_object x; + + fmt_stream = fmt_stream0; + ctl_origin = ctl_origin0; + ctl_index = 0; + ctl_end = ctl_end0; + +LOOP: + if (ctl_index >= ctl_end) + return; + if ((c = ctl_advance()) != '~') { + WRITEC_STREAM(c, fmt_stream); + goto LOOP; + } + n = 0; + for (;;) { + switch (c = ctl_advance()) { + case ',': + fmt_param[n].fmt_param_type = NONE; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + DIGIT: + i = 0; + do { + i = i*10 + (c - '0'); + c = ctl_advance(); + } while (isdigit(c)); + fmt_param[n].fmt_param_type = INT; + fmt_param[n].fmt_param_value = i; + break; + + case '+': + c = ctl_advance(); + if (!isdigit(c)) + fmt_error("digit expected"); + goto DIGIT; + + case '-': + c = ctl_advance(); + if (!isdigit(c)) + fmt_error("digit expected"); + i = 0; + do { + i = i*10 + (c - '0'); + c = ctl_advance(); + } while (isdigit(c)); + fmt_param[n].fmt_param_type = INT; + fmt_param[n].fmt_param_value = -i; + break; + + case '\'': + fmt_param[n].fmt_param_type = CHAR; + fmt_param[n].fmt_param_value = ctl_advance(); + c = ctl_advance(); + break; + + case 'v': case 'V': + x = fmt_advance(); + if (FIXNUMP(x)) { + fmt_param[n].fmt_param_type = INT; + fmt_param[n].fmt_param_value = fix(x); + } else if (type_of(x) == t_character) { + fmt_param[n].fmt_param_type = CHAR; + fmt_param[n].fmt_param_value = CHAR_CODE(x); + } else + fmt_error("illegal V parameter"); + c = ctl_advance(); + break; + + case '#': + fmt_param[n].fmt_param_type = INT; + fmt_param[n].fmt_param_value = fmt_end - fmt_index; + c = ctl_advance(); + break; + + default: + if (n > 0) + fmt_error("illegal ,"); + else + goto DIRECTIVE; + } + n++; + if (c != ',') + break; + } + +DIRECTIVE: + colon = atsign = FALSE; + if (c == ':') { + colon = TRUE; + c = ctl_advance(); + } + if (c == '@@') { + atsign = TRUE; + c = ctl_advance(); + } + fmt_nparam = n; + switch (c) { + case 'a': case 'A': + fmt_ascii(colon, atsign); + break; + + case 's': case 'S': + fmt_S_expression(colon, atsign); + break; + + case 'd': case 'D': + fmt_decimal(colon, atsign); + break; + + case 'b': case 'B': + fmt_binary(colon, atsign); + break; + + case 'o': case 'O': + fmt_octal(colon, atsign); + break; + + case 'x': case 'X': + fmt_hexadecimal(colon, atsign); + break; + + case 'r': case 'R': + fmt_radix(colon, atsign); + break; + + case 'p': case 'P': + fmt_plural(colon, atsign); + break; + + case 'c': case 'C': + fmt_character(colon, atsign); + break; + + case 'f': case 'F': + fmt_fix_float(colon, atsign); + break; + + case 'e': case 'E': + fmt_exponential_float(colon, atsign); + break; + + case 'g': case 'G': + fmt_general_float(colon, atsign); + break; + + case '$': + fmt_dollars_float(colon, atsign); + break; + + case '%': + fmt_percent(colon, atsign); + break; + + case '&': + fmt_ampersand(colon, atsign); + break; + + case '|': + fmt_bar(colon, atsign); + break; + + case '~': + fmt_tilde(colon, atsign); + break; + + case '\n': + case '\r': + fmt_newline(colon, atsign); + break; + + case 't': case 'T': + fmt_tabulate(colon, atsign); + break; + + case '*': + fmt_asterisk(colon, atsign); + break; + + case '?': + fmt_indirection(colon, atsign); + break; + + case '(': + fmt_case(colon, atsign); + break; + + case '[': + fmt_conditional(colon, atsign); + break; + + case '{': + fmt_iteration(colon, atsign); + break; + + case '<': + fmt_justification(colon, atsign); + break; + + case '^': + fmt_up_and_out(colon, atsign); + break; + + case ';': + fmt_semicolon(colon, atsign); + break; + + default: + fmt_error("illegal directive"); + } + goto LOOP; +} + +void +init_format(void) +{ + fmt_temporary_stream = make_string_output_stream(64); + register_root(&fmt_temporary_stream); + fmt_temporary_string = fmt_temporary_stream->stream.object0; + + SYM_VAL(siVindent_formatted_output) = Cnil; +} diff --git a/src/c/gbc-new.d b/src/c/gbc-new.d new file mode 100644 index 000000000..a27113000 --- /dev/null +++ b/src/c/gbc-new.d @@ -0,0 +1,989 @@ +/* + gbc.c -- Garbage collector. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi and William F. Schelter. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "page.h" + +/******************************* EXPORTS ******************************/ + +bool GC_enable; +int gc_time; /* Beppe */ + +/******************************* ------- ******************************/ + +/* + mark_table[m]:i represents word w = 128*m + 4*i, where m = addr-DATA_START. + Therefore m = w >> 7, i = (w / 4) % 32 = (w >> 2) & 0x1f. +*/ + +static int *mark_table; + +static void inline +set_mark_bit(void *x) { + int w = (int)x; + int m = (w - DATA_START) >> 7; + int i = (w >> 2) & 0x1f; + mark_table[m] |= (1 << i); +} +static int inline +get_mark_bit(void *x) { + int w = (int)x; + int m = (w - DATA_START) >> 7; + int i = (w >> 2) & 0x1f; + return (mark_table[m] >> i) & 1; +} + +#define inheap(pp) ((unsigned long)(pp) < (unsigned long)heap_end) +#define VALID_DATA_ADDRESS(pp) \ + !IMMEDIATE(pp) && (cl_index)DATA_START <= (cl_index)(pp) && (cl_index)(pp) < (cl_index)heap_end + +cl_object siVgc_verbose; +cl_object siVgc_message; + +static bool debug = FALSE; +static int maxpage; + +#define GC_ROOT_MAX 200 +static cl_object *gc_root[GC_ROOT_MAX]; +static int gc_roots; + +static bool collect_blocks; + +/* + We must register location, since value may be reassigned (e.g. malloc_list) + */ + +static void _mark_object (cl_object x); +static void _mark_contblock (void *p, size_t s); +extern void sigint (void); + +void +register_root(cl_object *p) +{ + if (gc_roots >= GC_ROOT_MAX) + error("too many roots"); + gc_root[gc_roots++] = p; +} + +@(defun gc (area) +@ + if (!GC_enabled()) + error("GC is not enabled"); + if (Null(area)) + gc(t_cons); + else + gc(t_contiguous); + @(return) +@) + +/*---------------------------------------------------------------------- + * Mark phase + *---------------------------------------------------------------------- + */ + +/* Whenever two arrays are linked together by displacement, + if one is live, the other will be made live */ +#define mark_displaced(ar) mark_object(ar) +#define mark_contblock(x,s) {if (collect_blocks) _mark_contblock(x,s); } +#if 1 +#define mark_object(x) if ((x != OBJNULL) && !IMMEDIATE(x)) _mark_object(x) +#define mark_next(a) if ((a != OBJNULL) && !IMMEDIATE(a)) { x=(a); goto BEGIN; } +#else +#define mark_object(x) _mark_object(x) +#define mark_next(a) x=(a); goto BEGIN +#endif + +/* We make bitvectors multiple of sizeof(int) in size allocated + Assume 8 = number of bits in char */ +#define W_SIZE (8*sizeof(int)) + +static void +_mark_object(cl_object x) +{ + size_t i, j; + cl_object *p, y; + char *cp; + + cs_check(x); +BEGIN: +#if 0 + /* We cannot get here because mark_object() and mark_next() already check this */ + if (IMMEDIATE(x)) return; /* fixnum, character or locative */ + if (x == OBJNULL) + return; +#endif + if (get_mark_bit(x)) + return; + set_mark_bit(x); + + switch (type_of(x)) { + + case t_bignum: + if (collect_blocks) { + /* GMP may set num.alloc before actually allocating anything. + With these checks we make sure we do not move anything + we don't have to. Besides, we use big_dim as the size + of the object, because big_size might even be smaller. + */ + char *limbs = (char *)x->big.big_limbs; + size_t size = x->big.big_dim * sizeof(mp_limb_t); + if (size) mark_contblock(limbs, size); + } + break; + + case t_ratio: + mark_object(x->ratio.num); + mark_next(x->ratio.den); + break; + + case t_shortfloat: + case t_longfloat: + break; + + case t_complex: + mark_object(x->complex.imag); + mark_next(x->complex.real); + break; + + case t_character: + break; + + case t_symbol: + mark_object(x->symbol.name); + mark_object(x->symbol.plist); + mark_object(SYM_FUN(x)); + mark_next(SYM_VAL(x)); + break; + + case t_package: + mark_object(x->pack.name); + mark_object(x->pack.nicknames); + mark_object(x->pack.shadowings); + mark_object(x->pack.uses); + mark_object(x->pack.usedby); + mark_object(x->pack.internal); + mark_next(x->pack.external); + break; + + case t_cons: + mark_object(CAR(x)); + mark_next(CDR(x)); + break; + + case t_hashtable: + mark_object(x->hash.rehash_size); + mark_object(x->hash.threshold); + if (x->hash.data == NULL) + break; + for (i = 0, j = x->hash.size; i < j; i++) { + mark_object(x->hash.data[i].key); + mark_object(x->hash.data[i].value); + } + mark_contblock(x->hash.data, j * sizeof(struct hashtable_entry)); + break; + + case t_array: + mark_contblock(x->array.dims, sizeof(x->array.dims[0])*x->array.rank); + case t_vector: + if ((y = x->array.displaced) != Cnil) + mark_displaced(y); + cp = (char *)x->array.self.t; + if (cp == NULL) + break; + switch ((enum aelttype)x->array.elttype) { + case aet_object: + if (x->array.displaced == Cnil || CAR(x->array.displaced) == Cnil) { + cl_object *p = x->array.self.t; + cl_index i; + if (x->array.t == t_vector && x->vector.hasfillp) + i = x->vector.fillp; + else + i = x->vector.dim; + while (i-- > 0) + mark_object(p[i]); + } + j = sizeof(cl_object)*x->array.dim; + break; + case aet_ch: + j = x->array.dim; + break; + case aet_bit: + j = sizeof(int) * ((x->vector.offset + x->vector.dim + W_SIZE -1)/W_SIZE); + break; + case aet_fix: + j = x->array.dim * sizeof(cl_fixnum); + break; + case aet_sf: + j = x->array.dim * sizeof(float); + break; + case aet_lf: + j = x->array.dim * sizeof(double); + break; + default: + error("Allocation botch: unknown array element type"); + } + goto COPY_ARRAY; + case t_string: + if ((y = x->string.displaced) != Cnil) + mark_displaced(y); + cp = x->string.self; + if (cp == NULL) + break; + j = x->string.dim; + COPY_ARRAY: + mark_contblock(cp, j); + break; + case t_bitvector: + if ((y = x->vector.displaced) != Cnil) + mark_displaced(y); + cp = x->vector.self.bit; + if (cp == NULL) + break; + j= sizeof(int) * ((x->vector.offset + x->vector.dim + W_SIZE -1)/W_SIZE); + goto COPY_ARRAY; + +#ifndef CLOS + case t_structure: + mark_object(x->str.name); + p = x->str.self; + if (p == NULL) + break; + for (i = 0, j = x->str.length; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; +#endif CLOS + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_closed: + /* Rest of fields are NULL */ + mark_next(x->stream.object1); + break; + case smm_input: + case smm_output: + case smm_io: + case smm_probe: + mark_object(x->stream.object0); + mark_object(x->stream.object1); + mark_contblock(x->stream.buffer, BUFSIZ); + break; + + case smm_synonym: + mark_next(x->stream.object0); + break; + + case smm_broadcast: + case smm_concatenated: + mark_next(x->stream.object0); + break; + + case smm_two_way: + case smm_echo: + mark_object(x->stream.object0); + mark_next(x->stream.object1); + break; + + case smm_string_input: + case smm_string_output: + mark_next(x->stream.object0); + break; + + default: + error("mark stream botch"); + } + break; + + case t_random: + break; + + case t_readtable: + if (x->readtable.table == NULL) + break; + mark_contblock((char *)(x->readtable.table), RTABSIZE*sizeof(struct readtable_entry)); + for (i = 0; i < RTABSIZE; i++) { + cl_object *p = x->readtable.table[i].dispatch_table; + mark_object(x->readtable.table[i].macro); + if (p != NULL) { + mark_contblock(p, RTABSIZE*sizeof(cl_object)); + for (j = 0; j < RTABSIZE; j++) + mark_object(p[j]); + } + } + break; + + case t_pathname: + mark_object(x->pathname.host); + mark_object(x->pathname.device); + mark_object(x->pathname.directory); + mark_object(x->pathname.name); + mark_object(x->pathname.type); + mark_object(x->pathname.version); + break; + + case t_bytecodes: { + cl_index i, size; + size = x->bytecodes.size; + mark_object(x->bytecodes.lex); + mark_contblock(x->bytecodes.data, size * sizeof(cl_object)); + for (i=0; ibytecodes.data[i]); + break; + } + case t_cfun: + mark_object(x->cfun.block); + mark_object(x->cfun.name); + break; + + case t_cclosure: + mark_object(x->cfun.block); + mark_object(x->cclosure.env); + break; + +#ifdef THREADS + case t_cont: + mark_next(x->cn.cn_thread); + break; + + case t_thread: +/* Already marked by malloc + mark_contblock(x->thread.data, x->thread.size); + */ + mark_next(x->thread.entry); + break; +#endif THREADS +#ifdef CLOS + case t_instance: + mark_object(x->instance.class); + p = x->instance.slots; + if (p == NULL) + break; + for (i = 0, j = x->instance.length; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; + + case t_gfun: + mark_object(x->gfun.name); + mark_object(x->gfun.method_hash); + mark_object(x->gfun.instance); + p = x->gfun.specializers; + if (p == NULL) + break; + for (i = 0, j = x->gfun.arg_no; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; +#endif CLOS + case t_codeblock: + mark_object(x->cblock.name); + mark_contblock(x->cblock.start, x->cblock.size); + if (x->cblock.data) { + cl_index i = x->cblock.data_size; + cl_object *p = x->cblock.data; + while (i--) + mark_object(p[i]); + } + break; + default: + if (debug) + printf("\ttype = %d\n", type_of(x)); + error("mark botch"); + } +} + +static void +mark_stack_conservative(int *top, int *bottom) +{ + int p, m; + cl_object x; + struct typemanager *tm; + register int *j; + + if (debug) { printf("Traversing C stack .."); fflush(stdout); } + + /* On machines which align local pointers on multiple of 2 rather + than 4 we need to mark twice + + if (offset) mark_stack_conservative(bottom, ((char *) top) + offset, 0); + */ + for (j = top ; j >= bottom ; j--) { + /* improved Beppe: */ + if (VALID_DATA_ADDRESS(*j) && type_map[p = page(*j)] < (char)t_end) { + tm = tm_of((enum type)type_map[p]); + x = (cl_object)(*j - (*j - (int)pagetochar(p)) % tm->tm_size); + if (!get_mark_bit(x)) + mark_object(x); + } + } + if (debug) {printf(". done.\n"); fflush(stdout); } +} + +static void +mark_phase(void) +{ + register int i; + register struct package *pp; + register bds_ptr bdp; + register frame_ptr frp; + register ihs_ptr ihsp; + + mark_object(Cnil); + mark_object(Ct); + +#ifdef THREADS + { + pd *pdp; + lpd *old_clwp = clwp; + + for (pdp = running_head; pdp != (pd *)NULL; pdp = pdp->pd_next) { + + clwp = pdp->pd_lpd; +#endif THREADS + + for (i=0; ibds_sym); + mark_object(bdp->bds_val); + } + + for (frp = frs_org; frp <= frs_top; frp++) { + mark_object(frp->frs_val); + mark_object(frp->frs_lex); + } + + for (ihsp = ihs_org; ihsp <= ihs_top; ihsp++) { + mark_object(ihsp->ihs_function); + mark_object(ihsp->ihs_base); + } + + mark_object(lex_env); + +#ifdef THREADS + /* added to mark newly allocated objects */ + mark_object(clwp->lwp_alloc_temporary); + mark_object(clwp->lwp_fmt_temporary_stream); + mark_object(clwp->lwp_PRINTstream); + mark_object(clwp->lwp_PRINTcase); + mark_object(clwp->lwp_READtable); + mark_object(clwp->lwp_delimiting_char); + mark_object(clwp->lwp_gensym_prefix); + mark_object(clwp->lwp_gentemp_prefix); + mark_object(clwp->lwp_token); + + /* (current-thread) can return it at any time + */ + mark_object(clwp->lwp_thread); +#endif THREADS + + /* now collect from the c-stack of the thread ... */ + + { int *where; + volatile jmp_buf buf; + + /* ensure flushing of register caches */ + if (ecls_setjmp(buf) == 0) ecls_longjmp(buf, 1); + +#ifdef THREADS + if (clwp != old_clwp) /* is not the executing stack */ +# ifdef __linux + where = (int *)pdp->pd_env[0].__jmpbuf[0].__sp; +# else + where = (int *)pdp->pd_env[JB_SP]; +# endif + else +#endif THREADS + where = (int *)&where ; + + /* If the locals of type object in a C function could be + aligned other than on multiples of sizeof (char *) + we would have to mark twice */ + + if (where > cs_org) + mark_stack_conservative(where, cs_org); + else + mark_stack_conservative(cs_org, where); + } +#ifdef THREADS + } + clwp = old_clwp; + } +#endif THREADS + + /* mark roots */ + for (i = 0; i < gc_roots; i++) + mark_object(*gc_root[i]); + + /* mark registered symbols & keywords */ + { + const struct keyword_info *k; + const struct symbol_info *s; + for (k = all_keywords; k->loc != NULL; k++) + mark_object(*(k->loc)); + for (s = all_symbols; s->loc != NULL; s++) + mark_object(*(s->loc)); + } + + if (debug) { + printf("symbol navigation\n"); + fflush(stdout); + } +} + +static void +sweep_phase(void) +{ + register int i, j, k; + register cl_object x; + register char *p; + register struct typemanager *tm; + register cl_object f; + + Cnil->symbol.m = FALSE; + Ct->symbol.m = FALSE; + + if (debug) + printf("type map\n"); + + for (i = 0; i < maxpage; i++) { + if (type_map[i] == (int)t_contiguous) { + if (debug) { + printf("-"); + continue; + } + } + if (type_map[i] >= (int)t_end) + continue; + + tm = tm_of((enum type)type_map[i]); + + /* + general sweeper + */ + + if (debug) + printf("%c", tm->tm_name[0]); + + p = pagetochar(i); + f = tm->tm_free; + k = 0; + for (j = tm->tm_nppage; j > 0; --j, p += tm->tm_size) { + x = (cl_object)p; + if (!get_mark_bit(x)) { + ((struct freelist *)x)->f_link = f; + f = x; + k++; + } + } + tm->tm_free = f; + tm->tm_nfree += k; + tm->tm_nused -= k; + } + + if (debug) { + putchar('\n'); + fflush(stdout); + } +} + +static void +contblock_sweep_phase(void) +{ + register int i, j; + register char *s, *e, *p, *q; + register struct contblock *cbp; + + cb_pointer = NULL; + ncb = 0; + for (i = 0; i < maxpage;) { + if (type_map[i] != (int)t_contiguous) { + i++; + continue; + } + for (j = i+1; + j < maxpage && type_map[j] == (int)t_contiguous; + j++) + ; + s = pagetochar(i); + e = pagetochar(j); + for (p = s; p < e;) { + if (get_mark_bit((int *)p)) { + p += 4; + continue; + } + q = p + 4; + while (q < e && !get_mark_bit((int *)q)) + q += 4; + dealloc(p, q - p); + p = q + 4; + } + i = j + 1; + } + + if (debug) { + for (cbp = cb_pointer; cbp != NULL; cbp = cbp->cb_link) + printf("0x%p %d\n", cbp, cbp->cb_size); + fflush(stdout); + } +} + +cl_object (*GC_enter_hook)() = NULL; +cl_object (*GC_exit_hook)() = NULL; + + +#ifdef THREADS +/* + * We execute the GC routine in the main stack. + * The idea is to switch over the main stack that is stopped in the intha + * and to call the GC from there on garbage_parameter. Then you can switch + * back after. + * In addition the interrupt is disabled. + */ +static int i, j; +static sigjmp_buf old_env; +static int val; +static lpd *old_clwp; +static enum type t; +static bool stack_switched = FALSE; + +static enum type garbage_parameter; + +void +gc(enum type new_name) +{ + int tm; + int gc_start = runtime(); + + start_critical_section(); + t = new_name; + garbage_parameter = new_name; +#else + +void +gc(enum type t) +{ + int i, j; + int tm; + int gc_start = runtime(); +#endif THREADS + + if (!GC_enabled()) + return; + + if (SYM_VAL(siVgc_verbose) != Cnil) { + printf("\n[GC .."); + /* To use this should add entries in tm_table for reloc and contig. + fprintf(stdout, "\n[GC for %d %s pages ..", + tm_of(t)->tm_npage, + tm_table[(int)t].tm_name + 1); */ + fflush(stdout); + } + + debug = symbol_value(siVgc_message) != Cnil; + +#ifdef THREADS + if (clwp != &main_lpd) { + if (debug) { + printf("*STACK SWITCH*\n"); + fflush (stdout); + } + + stack_switched = TRUE; + val = sigsetjmp(old_env, 1); + if (val == 0) { + /* informations used by the garbage collector need to be updated */ +# ifdef __linux + running_head->pd_env[0].__jmpbuf[0].__sp = old_env[0].__jmpbuf[0].__sp; +# else + running_head->pd_env[JB_SP] = old_env[JB_SP]; +# endif + old_clwp = clwp; + Values = main_lpd.lwp_Values; + clwp = &main_lpd; + siglongjmp(main_pd.pd_env, 2); /* new line */ + } + } + + else val = 1; + + if (val == 1) { + +#endif THREADS + + if (GC_enter_hook != NULL) + (*GC_enter_hook)(0); + + interrupt_enable = FALSE; + + collect_blocks = t > t_end; + if (collect_blocks) + cbgccount++; + else + tm_table[(int)t].tm_gccount++; + + if (debug) { + if (collect_blocks) + printf("GC entered for collecting blocks\n"); + else + printf("GC entered for collecting %s\n", tm_table[(int)t].tm_name); + fflush(stdout); + } + + maxpage = page(heap_end); + + if (collect_blocks) { + /* + 1 page = 512 word + 512 bit = 16 word + */ + int mark_table_size = maxpage * (LISP_PAGESIZE / 32); + extern void resize_hole(size_t); + + if (holepage < mark_table_size*sizeof(int)/LISP_PAGESIZE + 1) + new_holepage = mark_table_size*sizeof(int)/LISP_PAGESIZE + 1; + if (new_holepage < HOLEPAGE) + new_holepage = HOLEPAGE; + resize_hole(new_holepage); + + mark_table = (int*)heap_end; + for (i = 0; i < mark_table_size; i++) + mark_table[i] = 0; + } + + if (debug) { + printf("mark phase\n"); + fflush(stdout); + tm = runtime(); + } + mark_phase(); + if (debug) { + printf("mark ended (%d)\n", runtime() - tm); + printf("sweep phase\n"); + fflush(stdout); + tm = runtime(); + } + sweep_phase(); + if (debug) { + printf("sweep ended (%d)\n", runtime() - tm); + fflush(stdout); + } + + if (t == t_contiguous) { + if (debug) { + printf("contblock sweep phase\n"); + fflush(stdout); + tm = runtime(); + } + contblock_sweep_phase(); + if (debug) + printf("contblock sweep ended (%d)\n", runtime() - tm); + } + + if (debug) { + for (i = 0, j = 0; i < (int)t_end; i++) { + if (tm_table[i].tm_type == (enum type)i) { + printf("%13s: %8d used %8d free %4d/%d pages\n", + tm_table[i].tm_name, + tm_table[i].tm_nused, + tm_table[i].tm_nfree, + tm_table[i].tm_npage, + tm_table[i].tm_maxpage); + j += tm_table[i].tm_npage; + } else + printf("%13s: linked to %s\n", + tm_table[i].tm_name, + tm_table[(int)tm_table[i].tm_type].tm_name); + } + printf("contblock: %d blocks %d pages\n", ncb, ncbpage); + printf("hole: %d pages\n", holepage); + printf("GC ended\n"); + fflush(stdout); + } + + interrupt_enable = TRUE; + + if (GC_exit_hook != NULL) + (*GC_exit_hook)(); + +#ifdef THREADS + + /* + * Back in the right stack + */ + + if (stack_switched) { + if (debug) { + printf("*STACK BACK*\n"); + fflush (stdout); + } + + stack_switched = FALSE; + + end_critical_section(); /* we get here from the GC call in scheduler */ + + clwp = old_clwp; + Values = clwp->lwp_Values; + siglongjmp(old_env, 2); + } + } +#endif THREADS + + gc_time += (gc_start = runtime() - gc_start); + + if (SYM_VAL(siVgc_verbose) != Cnil) { + /* Don't use fprintf since on Linux it calls malloc() */ + printf(". finished in %.2f\"]", gc_start/60.0); + fflush(stdout); + } + +#ifdef unix + if (interrupt_flag) sigint(); +#endif unix + +#ifdef THREADS + end_critical_section(); +#endif THREADS +} + +/* + *---------------------------------------------------------------------- + * + * mark_contblock -- + * sets the mark bit for words from address p to address p+s. + * Both p and p+s are rounded to word boundaries. + * + * Results: + * none. + * + * Side effects: + * mark_table + * + *---------------------------------------------------------------------- + */ + +static void +_mark_contblock(void *x, size_t s) +{ + register char *p = x, *q; + register ptrdiff_t pg = page(p); + + if (pg < 0 || (enum type)type_map[pg] != t_contiguous) + return; +#if 1 + q = p + s; + p = (char *)((int)p&~3); + q = (char *)(((int)q+3)&~3); + for (; p < q; p+= 4) + set_mark_bit(p); +#elif 0 + { + int bit_start = ((int)p - DATA_START) >> 2; + int bit_end = ((int)p + s + 3 - DATA_START) >> 2; + int *w = &mark_table[bit_start >> 5]; + int b = bit_start & (32 - 1); + int mask = ~0 << b; + int bits = b + bit_end - bit_start; + while (bits >= 32) { + *w |= mask; + w++; + bits -= 32; + mask = ~0; + } + mask &= ~(~0 << bits); + *w |= mask; + } +#else + { + int bit_start = ((int)p - DATA_START) >> 2; + int bits = ((int)p + s + 3 - DATA_START) >> 2 - bit_start; + int mask = 1 << bit_start & (32 - 1); + int *w = &mark_table[bit_start >> 5]; + while (bits) { + *w |= mask; + mask <<= 1; + if (!mask) { + mask = 1; + w++; + } + } + } +#endif +} + +/*---------------------------------------------------------------------- + * Utilities + *---------------------------------------------------------------------- + */ + +@(defun si::room_report () + int i; + cl_object *tl; +@ + NValues = 8; + VALUES(0) = MAKE_FIXNUM(real_maxpage); + VALUES(1) = MAKE_FIXNUM(available_pages()); + VALUES(2) = MAKE_FIXNUM(ncbpage); + VALUES(3) = MAKE_FIXNUM(maxcbpage); + VALUES(4) = MAKE_FIXNUM(ncb); + VALUES(5) = MAKE_FIXNUM(cbgccount); + VALUES(6) = MAKE_FIXNUM(holepage); + VALUES(7) = Cnil; + tl = &VALUES(7); + for (i = 0; i < (int)t_end; i++) { + if (tm_table[i].tm_type == (enum type)i) { + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_nused), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_nfree), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_npage), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_maxpage), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_gccount), Cnil)); + } else { + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_type), Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + } + } + return VALUES(0); +@) + +@(defun si::reset_gc_count () + int i; +@ + cbgccount = 0; + for (i = 0; i < (int)t_end; i++) + tm_table[i].tm_gccount = 0; + @(return) +@) + +@(defun si::gc_time () +@ + @(return MAKE_FIXNUM(gc_time)) +@) + +void +init_GC(void) +{ + register_root(&siVgc_verbose); + register_root(&siVgc_message); + siVgc_verbose = make_si_special("*GC-VERBOSE*", Cnil); + siVgc_message = make_si_special("*GC-MESSAGE*", Cnil); + GC_enable(); + gc_time = 0; +} diff --git a/src/c/gbc.d b/src/c/gbc.d new file mode 100644 index 000000000..5302fec32 --- /dev/null +++ b/src/c/gbc.d @@ -0,0 +1,1017 @@ +/* + gbc.c -- Garbage collector. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi and William F. Schelter. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "page.h" + +/******************************* EXPORTS ******************************/ + +bool GC_enable; +int gc_time; /* Beppe */ + +/******************************* ------- ******************************/ + +/* + mark_table[m]:i represents word w = 128*m + 4*i, where m = addr-DATA_START. + Therefore m = w >> 7, i = (w / 4) % 32 = (w >> 2) & 0x1f. +*/ + +static int *mark_table; + +#define MTbit(x) (((((int)(char*)x) >> 2) & 0x1f)) +#define MTword(x) mark_table[((int)(char*)x - DATA_START) >> 7] +#if 1 +#define get_mark_bit(x) (MTword(x) >> MTbit(x) & 1) +#define set_mark_bit(x) (MTword(x) |= (1 << MTbit(x))) +#define clear_mark_bit(x) (MTword(x) ~= (~1 << MTbit(x))) +#else /* !__GNUC__ */ +static void inline +set_mark_bit(int *x) { + int w = (int)x; + int m = (w - DATA_START) >> 7; + int i = (w >> 2) & 0x1f; + mark_table[m] |= (1 << i); +} +static int inline +get_mark_bit(int *x) { + int w = (int)x; + int m = (w - DATA_START) >> 7; + int i = (w >> 2) & 0x1f; + return (mark_table[m] >> i) & 1; +} +#endif /* __GNUC__ */ + + +#define inheap(pp) ((unsigned long)(pp) < (unsigned long)heap_end) +#define VALID_DATA_ADDRESS(pp) \ + !IMMEDIATE(pp) && (cl_index)DATA_START <= (cl_index)(pp) && (cl_index)(pp) < (cl_index)heap_end + +cl_object siVgc_verbose; +cl_object siVgc_message; + +static bool debug = FALSE; +static int maxpage; + +#define GC_ROOT_MAX 200 +static cl_object *gc_root[GC_ROOT_MAX]; +static int gc_roots; + +static bool collect_blocks; + +/* + We must register location, since value may be reassigned (e.g. malloc_list) + */ + +static void _mark_object (cl_object x); +static void _mark_contblock (void *p, size_t s); +extern void sigint (void); + +void +register_root(cl_object *p) +{ + if (gc_roots >= GC_ROOT_MAX) + error("too many roots"); + gc_root[gc_roots++] = p; +} + +@(defun gc (area) +@ + if (!GC_enabled()) + error("GC is not enabled"); + if (Null(area)) + gc(t_cons); + else + gc(t_contiguous); + @(return) +@) + +/*---------------------------------------------------------------------- + * Mark phase + *---------------------------------------------------------------------- + */ + +/* Whenever two arrays are linked together by displacement, + if one is live, the other will be made live */ +#define mark_displaced(ar) mark_object(ar) +#define mark_contblock(x,s) {if (collect_blocks) _mark_contblock(x,s); } +#if 1 +#define mark_object(x) if ((x != OBJNULL) && !IMMEDIATE(x)) _mark_object(x) +#define mark_next(a) if ((a != OBJNULL) && !IMMEDIATE(a)) { x=(a); goto BEGIN; } +#else +#define mark_object(x) _mark_object(x) +#define mark_next(a) x=(a); goto BEGIN +#endif + +/* We make bitvectors multiple of sizeof(int) in size allocated + Assume 8 = number of bits in char */ +#define W_SIZE (8*sizeof(int)) + +static void +_mark_object(cl_object x) +{ + size_t i, j; + cl_object *p, y; + char *cp; + + cs_check(x); +BEGIN: +#if 0 + /* We cannot get here because mark_object() and mark_next() already check this */ + if (IMMEDIATE(x)) return; /* fixnum, character or locative */ + if (x == OBJNULL) + return; +#endif + if (x->d.m) { + if (x->d.m == FREE) + error("mark_object: pointer to free object."); + else + return; + } + x->d.m = TRUE; + + switch (type_of(x)) { + + case t_bignum: + if (collect_blocks) { + /* GMP may set num.alloc before actually allocating anything. + With these checks we make sure we do not move anything + we don't have to. Besides, we use big_dim as the size + of the object, because big_size might even be smaller. + */ + char *limbs = (char *)x->big.big_limbs; + size_t size = x->big.big_dim * sizeof(mp_limb_t); + if (size) mark_contblock(limbs, size); + } + break; + + case t_ratio: + mark_object(x->ratio.num); + mark_next(x->ratio.den); + break; + + case t_shortfloat: + case t_longfloat: + break; + + case t_complex: + mark_object(x->complex.imag); + mark_next(x->complex.real); + break; + + case t_character: + break; + + case t_symbol: + mark_object(x->symbol.name); + mark_object(x->symbol.plist); + mark_object(SYM_FUN(x)); + mark_next(SYM_VAL(x)); + break; + + case t_package: + mark_object(x->pack.name); + mark_object(x->pack.nicknames); + mark_object(x->pack.shadowings); + mark_object(x->pack.uses); + mark_object(x->pack.usedby); + mark_object(x->pack.internal); + mark_next(x->pack.external); + break; + + case t_cons: + mark_object(CAR(x)); + mark_next(CDR(x)); + break; + + case t_hashtable: + mark_object(x->hash.rehash_size); + mark_object(x->hash.threshold); + if (x->hash.data == NULL) + break; + for (i = 0, j = x->hash.size; i < j; i++) { + mark_object(x->hash.data[i].key); + mark_object(x->hash.data[i].value); + } + mark_contblock(x->hash.data, j * sizeof(struct hashtable_entry)); + break; + + case t_array: + mark_contblock(x->array.dims, sizeof(x->array.dims[0])*x->array.rank); + case t_vector: + if ((y = x->array.displaced) != Cnil) + mark_displaced(y); + cp = (char *)x->array.self.t; + if (cp == NULL) + break; + switch ((enum aelttype)x->array.elttype) { + case aet_object: + if (x->array.displaced == Cnil || CAR(x->array.displaced) == Cnil) { + cl_object *p = x->array.self.t; + cl_index i; + if (x->array.t == t_vector && x->vector.hasfillp) + i = x->vector.fillp; + else + i = x->vector.dim; + while (i-- > 0) + mark_object(p[i]); + } + j = sizeof(cl_object)*x->array.dim; + break; + case aet_ch: + j = x->array.dim; + break; + case aet_bit: + j = sizeof(int) * ((x->vector.offset + x->vector.dim + W_SIZE -1)/W_SIZE); + break; + case aet_fix: + j = x->array.dim * sizeof(cl_fixnum); + break; + case aet_sf: + j = x->array.dim * sizeof(float); + break; + case aet_lf: + j = x->array.dim * sizeof(double); + break; + default: + error("Allocation botch: unknown array element type"); + } + goto COPY_ARRAY; + case t_string: + if ((y = x->string.displaced) != Cnil) + mark_displaced(y); + cp = x->string.self; + if (cp == NULL) + break; + j = x->string.dim; + COPY_ARRAY: + mark_contblock(cp, j); + break; + case t_bitvector: + if ((y = x->vector.displaced) != Cnil) + mark_displaced(y); + cp = x->vector.self.bit; + if (cp == NULL) + break; + j= sizeof(int) * ((x->vector.offset + x->vector.dim + W_SIZE -1)/W_SIZE); + goto COPY_ARRAY; + +#ifndef CLOS + case t_structure: + mark_object(x->str.name); + p = x->str.self; + if (p == NULL) + break; + for (i = 0, j = x->str.length; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; +#endif CLOS + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_closed: + /* Rest of fields are NULL */ + mark_next(x->stream.object1); + break; + case smm_input: + case smm_output: + case smm_io: + case smm_probe: + mark_object(x->stream.object0); + mark_object(x->stream.object1); + mark_contblock(x->stream.buffer, BUFSIZ); + break; + + case smm_synonym: + mark_next(x->stream.object0); + break; + + case smm_broadcast: + case smm_concatenated: + mark_next(x->stream.object0); + break; + + case smm_two_way: + case smm_echo: + mark_object(x->stream.object0); + mark_next(x->stream.object1); + break; + + case smm_string_input: + case smm_string_output: + mark_next(x->stream.object0); + break; + + default: + error("mark stream botch"); + } + break; + + case t_random: + break; + + case t_readtable: + if (x->readtable.table == NULL) + break; + mark_contblock((char *)(x->readtable.table), RTABSIZE*sizeof(struct readtable_entry)); + for (i = 0; i < RTABSIZE; i++) { + cl_object *p = x->readtable.table[i].dispatch_table; + mark_object(x->readtable.table[i].macro); + if (p != NULL) { + mark_contblock(p, RTABSIZE*sizeof(cl_object)); + for (j = 0; j < RTABSIZE; j++) + mark_object(p[j]); + } + } + break; + + case t_pathname: + mark_object(x->pathname.host); + mark_object(x->pathname.device); + mark_object(x->pathname.directory); + mark_object(x->pathname.name); + mark_object(x->pathname.type); + mark_object(x->pathname.version); + break; + + case t_bytecodes: { + cl_index i, size; + size = x->bytecodes.size; + mark_object(x->bytecodes.lex); + mark_contblock(x->bytecodes.data, size * sizeof(cl_object)); + for (i=0; ibytecodes.data[i]); + break; + } + case t_cfun: + mark_object(x->cfun.block); + mark_object(x->cfun.name); + break; + + case t_cclosure: + mark_object(x->cfun.block); + mark_object(x->cclosure.env); + break; + +#ifdef THREADS + case t_cont: + mark_next(x->cn.cn_thread); + break; + + case t_thread: +/* Already marked by malloc + mark_contblock(x->thread.data, x->thread.size); + */ + mark_next(x->thread.entry); + break; +#endif THREADS +#ifdef CLOS + case t_instance: + mark_object(x->instance.class); + p = x->instance.slots; + if (p == NULL) + break; + for (i = 0, j = x->instance.length; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; + + case t_gfun: + mark_object(x->gfun.name); + mark_object(x->gfun.method_hash); + mark_object(x->gfun.instance); + p = x->gfun.specializers; + if (p == NULL) + break; + for (i = 0, j = x->gfun.arg_no; i < j; i++) + mark_object(p[i]); + mark_contblock(p, j*sizeof(cl_object)); + break; +#endif CLOS + case t_codeblock: + mark_object(x->cblock.name); + mark_contblock(x->cblock.start, x->cblock.size); + if (x->cblock.data) { + cl_index i = x->cblock.data_size; + cl_object *p = x->cblock.data; + while (i--) + mark_object(p[i]); + } + break; + default: + if (debug) + printf("\ttype = %d\n", type_of(x)); + error("mark botch"); + } +} + +static void +mark_stack_conservative(int *top, int *bottom) +{ + int p, m; + cl_object x; + struct typemanager *tm; + register int *j; + + if (debug) { printf("Traversing C stack .."); fflush(stdout); } + + /* On machines which align local pointers on multiple of 2 rather + than 4 we need to mark twice + + if (offset) mark_stack_conservative(bottom, ((char *) top) + offset, 0); + */ + for (j = top ; j >= bottom ; j--) { + /* improved Beppe: */ + if (VALID_DATA_ADDRESS(*j) && type_map[p = page(*j)] < (char)t_end) { + tm = tm_of((enum type)type_map[p]); + x = (cl_object)(*j - (*j - (int)pagetochar(p)) % tm->tm_size); + m = x->d.m; + if (m != FREE && m != TRUE) { + if (m) { + fprintf(stderr, + "** bad value %d of d.m in gc page %d skipping mark **", + m, p); fflush(stderr); + } else + mark_object(x); + } + }} + if (debug) {printf(". done.\n"); fflush(stdout); } +} + +static void +mark_phase(void) +{ + register int i; + register struct package *pp; + register bds_ptr bdp; + register frame_ptr frp; + register ihs_ptr ihsp; + + mark_object(Cnil); + mark_object(Ct); + +#ifdef THREADS + { + pd *pdp; + lpd *old_clwp = clwp; + + for (pdp = running_head; pdp != (pd *)NULL; pdp = pdp->pd_next) { + + clwp = pdp->pd_lpd; +#endif THREADS + + for (i=0; ibds_sym); + mark_object(bdp->bds_val); + } + + for (frp = frs_org; frp <= frs_top; frp++) { + mark_object(frp->frs_val); + mark_object(frp->frs_lex); + } + + for (ihsp = ihs_org; ihsp <= ihs_top; ihsp++) { + mark_object(ihsp->ihs_function); + mark_object(ihsp->ihs_base); + } + + mark_object(lex_env); + +#ifdef THREADS + /* added to mark newly allocated objects */ + mark_object(clwp->lwp_alloc_temporary); + mark_object(clwp->lwp_fmt_temporary_stream); + mark_object(clwp->lwp_PRINTstream); + mark_object(clwp->lwp_PRINTcase); + mark_object(clwp->lwp_READtable); + mark_object(clwp->lwp_delimiting_char); + mark_object(clwp->lwp_gensym_prefix); + mark_object(clwp->lwp_gentemp_prefix); + mark_object(clwp->lwp_token); + + /* (current-thread) can return it at any time + */ + mark_object(clwp->lwp_thread); +#endif THREADS + + /* now collect from the c-stack of the thread ... */ + + { int *where; + volatile jmp_buf buf; + + /* ensure flushing of register caches */ + if (ecls_setjmp(buf) == 0) ecls_longjmp(buf, 1); + +#ifdef THREADS + if (clwp != old_clwp) /* is not the executing stack */ +# ifdef __linux + where = (int *)pdp->pd_env[0].__jmpbuf[0].__sp; +# else + where = (int *)pdp->pd_env[JB_SP]; +# endif + else +#endif THREADS + where = (int *)&where ; + + /* If the locals of type object in a C function could be + aligned other than on multiples of sizeof (char *) + we would have to mark twice */ + + if (where > cs_org) + mark_stack_conservative(where, cs_org); + else + mark_stack_conservative(cs_org, where); + } +#ifdef THREADS + } + clwp = old_clwp; + } +#endif THREADS + + /* mark roots */ + for (i = 0; i < gc_roots; i++) + mark_object(*gc_root[i]); + + /* mark registered symbols & keywords */ + { + const struct keyword_info *k; + const struct symbol_info *s; + for (k = all_keywords; k->loc != NULL; k++) + mark_object(*(k->loc)); + for (s = all_symbols; s->loc != NULL; s++) + mark_object(*(s->loc)); + } + + if (debug) { + printf("symbol navigation\n"); + fflush(stdout); + } +} + +static void +sweep_phase(void) +{ + register int i, j, k; + register cl_object x; + register char *p; + register struct typemanager *tm; + register cl_object f; + + Cnil->symbol.m = FALSE; + Ct->symbol.m = FALSE; + + if (debug) + printf("type map\n"); + + for (i = 0; i < maxpage; i++) { + if (type_map[i] == (int)t_contiguous) { + if (debug) { + printf("-"); + continue; + } + } + if (type_map[i] >= (int)t_end) + continue; + + tm = tm_of((enum type)type_map[i]); + + /* + general sweeper + */ + + if (debug) + printf("%c", tm->tm_name[0]); + + p = pagetochar(i); + f = tm->tm_free; + k = 0; + for (j = tm->tm_nppage; j > 0; --j, p += tm->tm_size) { + x = (cl_object)p; + if (x->d.m == FREE) + continue; + else if (x->d.m) { + x->d.m = FALSE; + continue; + } + ((struct freelist *)x)->f_link = f; + x->d.m = FREE; + f = x; + k++; + } + tm->tm_free = f; + tm->tm_nfree += k; + tm->tm_nused -= k; + } + + if (debug) { + putchar('\n'); + fflush(stdout); + } +} + +static void +contblock_sweep_phase(void) +{ + register int i, j; + register char *s, *e, *p, *q; + register struct contblock *cbp; + + cb_pointer = NULL; + ncb = 0; + for (i = 0; i < maxpage;) { + if (type_map[i] != (int)t_contiguous) { + i++; + continue; + } + for (j = i+1; + j < maxpage && type_map[j] == (int)t_contiguous; + j++) + ; + s = pagetochar(i); + e = pagetochar(j); + for (p = s; p < e;) { + if (get_mark_bit((int *)p)) { + p += 4; + continue; + } + q = p + 4; + while (q < e && !get_mark_bit((int *)q)) + q += 4; + dealloc(p, q - p); + p = q + 4; + } + i = j + 1; + } + + if (debug) { + for (cbp = cb_pointer; cbp != NULL; cbp = cbp->cb_link) + printf("0x%p %d\n", cbp, cbp->cb_size); + fflush(stdout); + } +} + +cl_object (*GC_enter_hook)() = NULL; +cl_object (*GC_exit_hook)() = NULL; + + +#ifdef THREADS +/* + * We execute the GC routine in the main stack. + * The idea is to switch over the main stack that is stopped in the intha + * and to call the GC from there on garbage_parameter. Then you can switch + * back after. + * In addition the interrupt is disabled. + */ +static int i, j; +static sigjmp_buf old_env; +static int val; +static lpd *old_clwp; +static enum type t; +static bool stack_switched = FALSE; + +static enum type garbage_parameter; + +void +gc(enum type new_name) +{ + int tm; + int gc_start = runtime(); + + start_critical_section(); + t = new_name; + garbage_parameter = new_name; +#else + +void +gc(enum type t) +{ + int i, j; + int tm; + int gc_start = runtime(); +#endif THREADS + + if (!GC_enabled()) + return; + + if (SYM_VAL(siVgc_verbose) != Cnil) { + printf("\n[GC .."); + /* To use this should add entries in tm_table for reloc and contig. + fprintf(stdout, "\n[GC for %d %s pages ..", + tm_of(t)->tm_npage, + tm_table[(int)t].tm_name + 1); */ + fflush(stdout); + } + + debug = symbol_value(siVgc_message) != Cnil; + +#ifdef THREADS + if (clwp != &main_lpd) { + if (debug) { + printf("*STACK SWITCH*\n"); + fflush (stdout); + } + + stack_switched = TRUE; + val = sigsetjmp(old_env, 1); + if (val == 0) { + /* informations used by the garbage collector need to be updated */ +# ifdef __linux + running_head->pd_env[0].__jmpbuf[0].__sp = old_env[0].__jmpbuf[0].__sp; +# else + running_head->pd_env[JB_SP] = old_env[JB_SP]; +# endif + old_clwp = clwp; + Values = main_lpd.lwp_Values; + clwp = &main_lpd; + siglongjmp(main_pd.pd_env, 2); /* new line */ + } + } + + else val = 1; + + if (val == 1) { + +#endif THREADS + + if (GC_enter_hook != NULL) + (*GC_enter_hook)(0); + + interrupt_enable = FALSE; + + collect_blocks = t > t_end; + if (collect_blocks) + cbgccount++; + else + tm_table[(int)t].tm_gccount++; + + if (debug) { + if (collect_blocks) + printf("GC entered for collecting blocks\n"); + else + printf("GC entered for collecting %s\n", tm_table[(int)t].tm_name); + fflush(stdout); + } + + maxpage = page(heap_end); + + if (collect_blocks) { + /* + 1 page = 512 word + 512 bit = 16 word + */ + int mark_table_size = maxpage * (LISP_PAGESIZE / 32); + extern void resize_hole(size_t); + + if (holepage < mark_table_size*sizeof(int)/LISP_PAGESIZE + 1) + new_holepage = mark_table_size*sizeof(int)/LISP_PAGESIZE + 1; + if (new_holepage < HOLEPAGE) + new_holepage = HOLEPAGE; + resize_hole(new_holepage); + + mark_table = (int*)heap_end; + for (i = 0; i < mark_table_size; i++) + mark_table[i] = 0; + } + + if (debug) { + printf("mark phase\n"); + fflush(stdout); + tm = runtime(); + } + mark_phase(); + if (debug) { + printf("mark ended (%d)\n", runtime() - tm); + printf("sweep phase\n"); + fflush(stdout); + tm = runtime(); + } + sweep_phase(); + if (debug) { + printf("sweep ended (%d)\n", runtime() - tm); + fflush(stdout); + } + + if (t == t_contiguous) { + if (debug) { + printf("contblock sweep phase\n"); + fflush(stdout); + tm = runtime(); + } + contblock_sweep_phase(); + if (debug) + printf("contblock sweep ended (%d)\n", runtime() - tm); + } + + if (debug) { + for (i = 0, j = 0; i < (int)t_end; i++) { + if (tm_table[i].tm_type == (enum type)i) { + printf("%13s: %8d used %8d free %4d/%d pages\n", + tm_table[i].tm_name, + tm_table[i].tm_nused, + tm_table[i].tm_nfree, + tm_table[i].tm_npage, + tm_table[i].tm_maxpage); + j += tm_table[i].tm_npage; + } else + printf("%13s: linked to %s\n", + tm_table[i].tm_name, + tm_table[(int)tm_table[i].tm_type].tm_name); + } + printf("contblock: %d blocks %d pages\n", ncb, ncbpage); + printf("hole: %d pages\n", holepage); + printf("GC ended\n"); + fflush(stdout); + } + + interrupt_enable = TRUE; + + if (GC_exit_hook != NULL) + (*GC_exit_hook)(); + +#ifdef THREADS + + /* + * Back in the right stack + */ + + if (stack_switched) { + if (debug) { + printf("*STACK BACK*\n"); + fflush (stdout); + } + + stack_switched = FALSE; + + end_critical_section(); /* we get here from the GC call in scheduler */ + + clwp = old_clwp; + Values = clwp->lwp_Values; + siglongjmp(old_env, 2); + } + } +#endif THREADS + + gc_time += (gc_start = runtime() - gc_start); + + if (SYM_VAL(siVgc_verbose) != Cnil) { + /* Don't use fprintf since on Linux it calls malloc() */ + printf(". finished in %.2f\"]", gc_start/60.0); + fflush(stdout); + } + +#ifdef unix + if (interrupt_flag) sigint(); +#endif unix + +#ifdef THREADS + end_critical_section(); +#endif THREADS +} + +/* + *---------------------------------------------------------------------- + * + * mark_contblock -- + * sets the mark bit for words from address p to address p+s. + * Both p and p+s are rounded to word boundaries. + * + * Results: + * none. + * + * Side effects: + * mark_table + * + *---------------------------------------------------------------------- + */ + +static void +_mark_contblock(void *x, size_t s) +{ + register char *p = x, *q; + register ptrdiff_t pg = page(p); + + if (pg < 0 || (enum type)type_map[pg] != t_contiguous) + return; +#if 1 + q = p + s; + p = (char *)((int)p&~3); + q = (char *)(((int)q+3)&~3); + for (; p < q; p+= 4) + set_mark_bit(p); +#elif 0 + { + int bit_start = ((int)p - DATA_START) >> 2; + int bit_end = ((int)p + s + 3 - DATA_START) >> 2; + int *w = &mark_table[bit_start >> 5]; + int b = bit_start & (32 - 1); + int mask = ~0 << b; + int bits = b + bit_end - bit_start; + while (bits >= 32) { + *w |= mask; + w++; + bits -= 32; + mask = ~0; + } + mask &= ~(~0 << bits); + *w |= mask; + } +#else + { + int bit_start = ((int)p - DATA_START) >> 2; + int bits = ((int)p + s + 3 - DATA_START) >> 2 - bit_start; + int mask = 1 << bit_start & (32 - 1); + int *w = &mark_table[bit_start >> 5]; + while (bits) { + *w |= mask; + mask <<= 1; + if (!mask) { + mask = 1; + w++; + } + } + } +#endif +} + +/*---------------------------------------------------------------------- + * Utilities + *---------------------------------------------------------------------- + */ + +@(defun si::room_report () + int i; + cl_object *tl; +@ + NValues = 8; + VALUES(0) = MAKE_FIXNUM(real_maxpage); + VALUES(1) = MAKE_FIXNUM(available_pages()); + VALUES(2) = MAKE_FIXNUM(ncbpage); + VALUES(3) = MAKE_FIXNUM(maxcbpage); + VALUES(4) = MAKE_FIXNUM(ncb); + VALUES(5) = MAKE_FIXNUM(cbgccount); + VALUES(6) = MAKE_FIXNUM(holepage); + VALUES(7) = Cnil; + tl = &VALUES(7); + for (i = 0; i < (int)t_end; i++) { + if (tm_table[i].tm_type == (enum type)i) { + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_nused), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_nfree), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_npage), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_maxpage), Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_gccount), Cnil)); + } else { + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(MAKE_FIXNUM(tm_table[i].tm_type), Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + tl = &CDR(*tl = CONS(Cnil, Cnil)); + } + } + return VALUES(0); +@) + +@(defun si::reset_gc_count () + int i; +@ + cbgccount = 0; + for (i = 0; i < (int)t_end; i++) + tm_table[i].tm_gccount = 0; + @(return) +@) + +@(defun si::gc_time () +@ + @(return MAKE_FIXNUM(gc_time)) +@) + +void +init_GC(void) +{ + register_root(&siVgc_verbose); + register_root(&siVgc_message); + siVgc_verbose = make_si_special("*GC-VERBOSE*", Cnil); + siVgc_message = make_si_special("*GC-MESSAGE*", Cnil); + GC_enable(); + gc_time = 0; +} diff --git a/src/c/gfun.d b/src/c/gfun.d new file mode 100644 index 000000000..9fb0755cc --- /dev/null +++ b/src/c/gfun.d @@ -0,0 +1,262 @@ +/* + gfun.c -- Dispatch for generic functions. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +cl_object siScompute_applicable_methods; +cl_object siScompute_effective_method; +cl_object siSgeneric_function_method_combination; +cl_object siSgeneric_function_method_combination_args; + +@(defun si::allocate_gfun (name arg_no ht) + cl_object x; + int n, i; +@ + if (type_of(ht) != t_hashtable) + FEwrong_type_argument(Shash_table, ht); + + x = alloc_object(t_gfun); + x->gfun.specializers = NULL; /* for GC sake */ + x->gfun.name = name; + x->gfun.method_hash = ht; + n = fixnnint(arg_no); + x->gfun.arg_no = n; + x->gfun.specializers = alloc_align(sizeof(cl_object)*n, sizeof(cl_object)); + for (i = 0; i < n; i++) + x->gfun.specializers[i] = OBJNULL; + x->gfun.instance = Cnil; + @(return x) +@) + +@(defun si::gfun_name (x) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + @(return x->gfun.name) +@) + +@(defun si::gfun_name_set (x name) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + x->gfun.name = name; + @(return x) +@) + +@(defun si::gfun_method_ht (x) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + @(return x->gfun.method_hash) +@) + +@(defun si::gfun_method_ht_set (x y) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + if (type_of(y) != t_hashtable) + FEwrong_type_argument(Shash_table, y); + x->gfun.method_hash = y; + @(return x) +@) + +@(defun si::gfun_spec_how_ref (x y) + int i; +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + if (!FIXNUMP(y) || + (i = fix(y)) < 0 || i >= x->gfun.arg_no) + FEerror("~S is an illegal spec_how index.", 1, y); + @(return x->gfun.specializers[i]) +@) + +@(defun si::gfun_spec_how_set (x y spec) + int i; +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + if (!FIXNUMP(y) || (i = fix(y)) >= x->gfun.arg_no) + FEerror("~S is an illegal spec_how index.", 1, y); + x->gfun.specializers[i] = spec; + @(return spec) +@) + +@(defun si::gfun_instance (x) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + @(return x->gfun.instance) +@) + +@(defun si::gfun_instance_set (x y) +@ + if (type_of(x) != t_gfun) + FEwrong_type_argument(Sdispatch_function, x); + if (type_of(y) != t_instance) + FEwrong_type_argument(Sinstance, y); + x->gfun.instance = y; + @(return x) +@) + +@(defun si::gfunp (x) +@ + @(return ((type_of(x) == t_gfun)? Ct : Cnil)) +@) + + +/* + * variation of gethash from hash.d, which takes an array of objects as key + * It also assumes that entries are never removed except by clrhash. + */ + +static struct hashtable_entry * +get_meth_hash(cl_object *keys, int argno, cl_object hashtable) +{ + int hsize; + struct hashtable_entry *e, *htable; + cl_object hkey, tlist; + register int i = 0; + int k, n; /* k added by chou */ + bool b = 1; + + hsize = hashtable->hash.size; + htable = hashtable->hash.data; + for (n = 0; n < argno; n++) + i += (int)keys[n] / 4; /* instead of: + i += hash_eql(keys[n]); + i += hash_eql(Cnil); + */ + for (i %= hsize, k = 0; k < hsize; i = (i + 1) % hsize, k++) { + e = &htable[i]; + hkey = e->key; + if (hkey == OBJNULL) + return(e); + for (n = 0, tlist = hkey; b && (n < argno); + n++, tlist = CDR(tlist)) + b &= (keys[n] == CAR(tlist)); + if (b) + return(&htable[i]); + } + internal_error("get_meth_hash"); +} + +@(defun si::method_ht_get (keylist table) + struct hashtable_entry *e; +@ + { int i, argn = length(keylist); + cl_object keys[argn]; /* __GNUC__ */ + + for (i = 0; i < argn; i++, keylist = CDR(keylist)) + keys[i] = CAR(keylist); + e = get_meth_hash(keys, argn, table); + } + @(return ((e->key == OBJNULL)? Cnil : e->value)) +@) + +static void +set_meth_hash(cl_object *keys, int argno, cl_object hashtable, cl_object value) +{ + struct hashtable_entry *e; + cl_object keylist, *p; + + if (hashtable->hash.entries + 1 >= fix(hashtable->hash.threshold)) + extend_hashtable(hashtable); + e = get_meth_hash(keys, argno, hashtable); + if (e->key == OBJNULL) + hashtable->hash.entries++; + keylist = Cnil; + for (p = keys + argno; p > keys; p--) keylist = CONS(p[-1], keylist); + e->key = keylist; + e->value = value; +} + +cl_object +gcall(int narg, cl_object fun, cl_object *args) +{ + cl_object func; + + { int i, spec_no; + struct hashtable_entry *e; + cl_object *spec_how = fun->gfun.specializers; + cl_object argtype[narg]; /* __GNUC__ */ + + if (narg < fun->gfun.arg_no) + FEerror("Generic function ~S requires more than ~R argument~:p.", + 2, fun->gfun.name, MAKE_FIXNUM(narg)); + for (i = 0, spec_no = 0; i < fun->gfun.arg_no; i++, spec_how++) { + if (*spec_how != Cnil) + argtype[spec_no++] = (ATOM(*spec_how) || + !member_eq(args[i], *spec_how)) ? + TYPE_OF(args[i]) : + args[i]; + } + + e = get_meth_hash(argtype, spec_no, fun->gfun.method_hash); + + if (e->key == OBJNULL) { + /* method not cached */ + register cl_object gf = fun->gfun.instance; + cl_object methods, meth_comb, meth_args, arglist = Cnil; + + i = narg; + while (i-- > 0) + arglist = CONS(args[i], arglist); + methods = _funcall(3, siScompute_applicable_methods, gf, arglist); + meth_comb = _funcall(2, siSgeneric_function_method_combination, gf); + meth_args = _funcall(2, siSgeneric_function_method_combination_args, + gf); + func = _funcall(5, siScompute_effective_method, gf, methods, + meth_comb, meth_args); + + /* update cache */ + set_meth_hash(argtype, spec_no, fun->gfun.method_hash, func); + } else + /* method is already cached */ + func = e->value; + } + switch (type_of(func)) { + + case t_cfun: + return APPLY(narg, *func->cfun.entry, args); + + case t_cclosure: + { int i; CSTACK(narg+1); + CPUSH(func->cclosure.env); + for (i = 0; i < narg; i++) + CPUSH(*args++); +#ifdef CCALL + return CCALL(narg+1, func->cclosure.entry); +#else + return APPLY(narg+1, func->cclosure.entry, CSTACK_BOT); +#endif CCALL + } + case t_bytecodes: + return apply(narg, func, args); + + default: + FEinvalid_function(func); + } +} + +@(defun si::set_compiled_function_name (fn new_name) + enum cl_type t = type_of(fn); +@ + if (t == t_cfun) + @(return (fn->cfun.name = new_name)) + if (t == t_bytecodes) + @(return (fn->bytecodes.data[0] = new_name)) + FEerror("~S is not a compiled-function.", 1, fn); +@) diff --git a/src/c/hash.d b/src/c/hash.d new file mode 100644 index 000000000..091d3f28c --- /dev/null +++ b/src/c/hash.d @@ -0,0 +1,540 @@ +/* + hash.d -- Hash tables. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +cl_object Seq; +cl_object Seql; +cl_object Sequal; + +cl_object Ksize; +cl_object Krehash_size; +cl_object Krehash_threshold; + + +/******************* + * CRC-32 ROUTINES * + *******************/ + +/* + * Lookup table for CRC-32 codes + */ + +static const cl_hashkey crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/* + * CRC-32 Updater + */ + +#define DO1ch(crc,c) crc = crc_table[((int)crc ^ (c)) & 0xff] ^ (crc >> 8) +#define DO1(crc,buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO2(crc,buf) DO1(crc,buf); DO1(crc,buf); +#define DO4(crc,buf) DO2(crc,buf); DO2(crc,buf); +#define DO8(crc,buf) DO4(crc,buf); DO4(crc,buf); + +cl_hashkey +update_crc32(cl_hashkey crc, const char *buf, cl_index len) +{ + while (len >= 8) { + DO8(crc,buf); + len -= 8; + } + if (len) do { + DO1(crc,buf); + } while (--len); + return crc; +} + + +static void corrupted_hash(cl_object hashtable) __attribute__((noreturn)); + +static void +corrupted_hash(cl_object hashtable) +{ + FEerror("internal error, corrupted hashtable ~S", 1, hashtable); +} + +cl_hashkey +hash_eql(cl_object x) +{ + register char *buffer; + register cl_index len; + register cl_hashkey h = 0; + BEGIN: + switch (type_of(x)) { + case t_bignum: + buffer = (char*)x->big.big_limbs; + len = abs(x->big.big_size) * sizeof(mp_limb_t); + break; + case t_ratio: + h = hash_eql(x->ratio.num); + x = x->ratio.den; + goto BEGIN; + case t_shortfloat: + buffer = (char*)&sf(x); + len = sizeof(sf(x)); + break; + case t_longfloat: + buffer = (char*)&lf(x); + len = sizeof(lf(x)); + break; + case t_complex: + h = hash_eql(x->complex.real); + x = x->complex.imag; + goto BEGIN; + case t_character: + return CHAR_CODE(x); + default: + return (cl_hashkey)x >> 2; + } + while (len >= 4) { + DO4(h, buffer); + len -= 4; + } + while (len--) + DO1(h, buffer); + return h; +} + +static cl_hashkey +_hash_equal(cl_hashkey h, int depth, cl_object x) +{ + char *buffer; + cl_index len; + + cs_check(x); +BEGIN: + if (depth++ > 3) return h; + switch (type_of(x)) { + case t_cons: + h = _hash_equal(h, depth, CAR(x)); + x = CDR(x); + goto BEGIN; + case t_symbol: + x = x->symbol.name; + case t_string: + buffer = x->string.self; + len = x->string.fillp; + break; + case t_pathname: + h = _hash_equal(h, depth, x->pathname.host); + h = _hash_equal(h, depth, x->pathname.device); + h = _hash_equal(h, depth, x->pathname.directory); + h = _hash_equal(h, depth, x->pathname.name); + h = _hash_equal(h, depth, x->pathname.type); + x = x->pathname.name; + goto BEGIN; +#if 0 /* !ANSI */ +#ifdef CLOS + case t_instance: + h += _hash_equal(CLASS_NAME(x), depth); + for (i = 0; i < x->instance.length; i++) + h += _hash_equal(x->instance.slots[i], depth); + return(h); +#else + case t_structure: + h += _hash_equal(x->str.name, depth); + for (i = 0; i < x->str.length; i++) + h += _hash_equal(x->str.self[i], depth); + return(h); +#endif CLOS +#endif /* !ANSI */ + case t_package: /* These two should actually */ + case t_bitvector: /* have visible changes under equal */ + default: + return h ^ hash_eql(x); + } + while (len >= 4) { + DO4(h, buffer); + len -= 4; + } + while (len--) + DO1(h, buffer); + return h; +} + +cl_hashkey +hash_equal(cl_object key) +{ + return _hash_equal(~(cl_hashkey)0, 0, key); +} + +static struct hashtable_entry * +search_hash(cl_object key, cl_object hashtable) +{ + cl_hashkey h; + cl_index hsize, i, j, k; + struct hashtable_entry *e; + cl_object hkey; + int htest; + bool b; + + htest = hashtable->hash.test; + hsize = hashtable->hash.size; + j = hsize; + switch (htest) { + case htt_eq: h = (cl_hashkey)key >> 2; break; + case htt_eql: h = hash_eql(key); break; + case htt_equal: h = _hash_equal(~(cl_hashkey)0, 0, key); break; + case htt_pack: h = _hash_equal(~(cl_hashkey)0, 0, key); break; + default: corrupted_hash(hashtable); + } + i = h % hsize; + h = h & 0xFFFF; + for (k = 0; k < hsize; i = (i + 1) % hsize, k++) { + e = &hashtable->hash.data[i]; + hkey = e->key; + if (hkey == OBJNULL) { + if (e->value == OBJNULL) + if (j == hsize) + return(e); + else + return(&hashtable->hash.data[j]); + else + if (j == hsize) + j = i; + else if (j == i) + /* this was never returning --wfs + but looping around with j=0 */ + return(e); + continue; + } + switch (htest) { + case htt_eq: b = key == hkey; break; + case htt_eql: b = eql(key, hkey); break; + case htt_equal: b = equal(key, hkey); break; + case htt_pack: b = (h==fix(hkey)) && string_eq(key,e->value->symbol.name); + break; + default: corrupted_hash(hashtable); + } + if (b) + return(&hashtable->hash.data[i]); + } + return(&hashtable->hash.data[j]); +} + +cl_object +gethash(cl_object key, cl_object hashtable) +{ + return search_hash(key, hashtable)->value; +} + +cl_object +gethash_safe(cl_object key, cl_object hashtable, cl_object def) +{ + struct hashtable_entry *e; + e = search_hash(key, hashtable); + if (e->key == OBJNULL) + return def; + else + return e->value; +} + +static void +add_new_to_hash(cl_object key, cl_object hashtable, cl_object value) +{ + int htest; + cl_hashkey h; + cl_index i, hsize; + struct hashtable_entry *e; + + htest = hashtable->hash.test; + hsize = hashtable->hash.size; + switch (htest) { + case htt_eq: h = (cl_hashkey)key / 4; break; + case htt_eql: h = hash_eql(key); break; + case htt_equal: h = _hash_equal(~(cl_hashkey)0, 0, key); break; + case htt_pack: h = _hash_equal(~(cl_hashkey)0, 0, key); break; + default: corrupted_hash(hashtable); + } + e = hashtable->hash.data; + for (i = h % hsize; ; i = (i + 1) % hsize) + if (e[i].key == OBJNULL) { + hashtable->hash.entries++; + if (htest == htt_pack) + e[i].key = MAKE_FIXNUM(h & 0xFFFF); + else + e[i].key = key; + e[i].value = value; + return; + } + corrupted_hashtable(); +} + +void +sethash(cl_object key, cl_object hashtable, cl_object value) +{ + cl_index i; + bool over; + struct hashtable_entry *e; + e = search_hash(key, hashtable); + if (e->key != OBJNULL) { + e->value = value; + return; + } + i = hashtable->hash.entries + 1; + if (i >= hashtable->hash.size) + over = TRUE; + else if (FIXNUMP(hashtable->hash.threshold)) + over = i >= (cl_index)fix(hashtable->hash.threshold); + else if (type_of(hashtable->hash.threshold) == t_shortfloat) + over = i >= hashtable->hash.size * sf(hashtable->hash.threshold); + else if (type_of(hashtable->hash.threshold) == t_longfloat) + over = i >= hashtable->hash.size * lf(hashtable->hash.threshold); + else + corrupted_hash(hashtable); + if (over) + extend_hashtable(hashtable); + add_new_to_hash(key, hashtable, value); +} + +void +extend_hashtable(cl_object hashtable) +{ + cl_object old, key; + cl_index old_size, new_size, i; + struct hashtable_entry *e; + old_size = hashtable->hash.size; + if (FIXNUMP(hashtable->hash.rehash_size)) + new_size = old_size + fix(hashtable->hash.rehash_size); + else if (type_of(hashtable->hash.rehash_size) == t_shortfloat) + new_size = old_size * sf(hashtable->hash.rehash_size); + else if (type_of(hashtable->hash.rehash_size) == t_longfloat) + new_size = old_size * lf(hashtable->hash.rehash_size); + else + corrupted_hash(hashtable); + if (new_size <= old_size) + new_size = old_size + 1; + old = alloc_object(t_hashtable); + old->hash = hashtable->hash; + hashtable->hash.data = NULL; /* for GC sake */ + hashtable->hash.size = new_size; + if (FIXNUMP(hashtable->hash.threshold)) + hashtable->hash.threshold = + MAKE_FIXNUM(fix(hashtable->hash.threshold) + + (new_size - old->hash.size)); + hashtable->hash.data = alloc_align(new_size * sizeof(struct hashtable_entry), + sizeof(cl_object)); + for (i = 0; i < new_size; i++) { + hashtable->hash.data[i].key = OBJNULL; + hashtable->hash.data[i].value = OBJNULL; + } + for (i = 0; i < old_size; i++) + if ((key = old->hash.data[i].key) != OBJNULL) { + if (hashtable->hash.test == htt_pack) + key = old->hash.data[i].value; + add_new_to_hash(key, hashtable, old->hash.data[i].value); + } +} + + +@(defun make_hash_table (&key (test Seql) + (size MAKE_FIXNUM(1024)) + (rehash_size make_shortfloat(1.5)) + (rehash_threshold make_shortfloat(0.7)) + &aux h) + enum httest htt; + cl_index i, hsize; +@ + if (test == Seq || test == SYM_FUN(Seq)) + htt = htt_eq; + else if (test == Seql || test == SYM_FUN(Seql)) + htt = htt_eql; + else if (test == Sequal || test == SYM_FUN(Sequal)) + htt = htt_equal; + else + FEerror("~S is an illegal hash-table test function.", + 1, test); + if (!FIXNUMP(size) || FIXNUM_MINUSP(size)) + FEerror("~S is an illegal hash-table size.", 1, size); + hsize = fix(size); + if ((FIXNUMP(rehash_size) && 0 < fix(rehash_size)) || + (type_of(rehash_size) == t_shortfloat && 1.0 < sf(rehash_size)) || + (type_of(rehash_size) == t_longfloat && 1.0 < lf(rehash_size))) + ; + else + FEerror("~S is an illegal hash-table rehash-size.", + 1, rehash_size); + if ((FIXNUMP(rehash_threshold) && + 0 < fix(rehash_threshold) && fix(rehash_threshold) < fix(size)) || + (type_of(rehash_threshold) == t_shortfloat && + 0.0 < sf(rehash_threshold) && sf(rehash_threshold) < 1.0) || + (type_of(rehash_threshold) == t_longfloat && + 0.0 < lf(rehash_threshold) && lf(rehash_threshold) < 1.0)) + ; + else + FEerror("~S is an illegal hash-table rehash-threshold.", + 1, rehash_threshold); + h = alloc_object(t_hashtable); + h->hash.test = htt; + h->hash.size = hsize; + h->hash.rehash_size = rehash_size; + h->hash.threshold = rehash_threshold; + h->hash.entries = 0; + h->hash.data = NULL; /* for GC sake */ + h->hash.data = alloc_align(hsize * sizeof(struct hashtable_entry), + sizeof(cl_object)); + for(i = 0; i < hsize; i++) { + h->hash.data[i].key = OBJNULL; + h->hash.data[i].value = OBJNULL; + } + @(return h) +@) + +@(defun hash_table_p (ht) +@ + @(return ((type_of(ht) == t_hashtable) ? Ct : Cnil)) +@) + +@(defun gethash (key ht &optional (no_value Cnil)) + struct hashtable_entry *e; +@ + assert_type_hash_table(ht); + e = search_hash(key, ht); + if (e->key != OBJNULL) + @(return e->value Ct) + else + @(return no_value Cnil) +@) + +@(defun si::hash_set (key ht val) +@ + assert_type_hash_table(ht); + sethash(key, ht, val); + @(return val) +@) + +bool +remhash(cl_object key, cl_object hashtable) +{ + struct hashtable_entry *e; + assert_type_hash_table(hashtable); + e = search_hash(key, hashtable); + if (e->key != OBJNULL) { + e->key = OBJNULL; + e->value = Cnil; + hashtable->hash.entries--; + return TRUE; + } + return FALSE; +} + +@(defun remhash (key ht) + struct hashtable_entry *e; +@ + @(return (remhash(key, ht)? Ct : Cnil)); +@) + +@(defun clrhash (ht) + cl_index i; +@ + assert_type_hash_table(ht); + for(i = 0; i < ht->hash.size; i++) { + ht->hash.data[i].key = OBJNULL; + ht->hash.data[i].value = OBJNULL; + } + ht->hash.entries = 0; + @(return ht) +@) + +@(defun hash_table_count (ht) +@ + assert_type_hash_table(ht); + @(return (MAKE_FIXNUM(ht->hash.entries))) +@) + +@(defun hash_table_rehash_size (ht) +@ + assert_type_hash_table(ht); + @(return ht->hash.rehash_size) +@) + +@(defun hash_table_rehash_threshold (ht) +@ + assert_type_hash_table(ht); + @(return ht->hash.threshold) +@) + +@(defun sxhash (key) +@ + @(return (MAKE_FIXNUM(_hash_equal(~(cl_hashkey)0, 0, key) & 0x7fffffff))) +@) + +@(defun maphash (fun ht) + cl_index i; +@ + assert_type_hash_table(ht); + for (i = 0; i < ht->hash.size; i++) { + if(ht->hash.data[i].key != OBJNULL) + funcall(3, fun, + ht->hash.data[i].key, + ht->hash.data[i].value); + } + @(return Cnil) +@) diff --git a/src/c/init.d b/src/c/init.d new file mode 100644 index 000000000..b2461a79a --- /dev/null +++ b/src/c/init.d @@ -0,0 +1,113 @@ +/* + init.c -- Lisp Initialization. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +/******************************* ------- ******************************/ + +extern void init_lisp_libs(void); + +void +init_lisp(void) +{ +#ifndef RUNTIME + function_entry_table = (void *)malloc(2 * function_entries_max * sizeof(void *)); +#endif + init_symbol(); + init_package(); + +#if !defined(GBC_BOEHM) + /* We need this because a lot of stuff is to be created */ + init_GC(); +#endif + + /* These must come _after_ init_symbol() and init_package() */ + init_all_keywords(); + init_all_symbols(); + init_all_functions(); + + SYM_VAL(Vpackage) = lisp_package; + SYM_VAL(Vgensym_counter) = MAKE_FIXNUM(0); + + init_typespec(); + init_number(); + init_character(); + init_file(); + init_read(); + init_print(); + init_pathname(); +#ifdef unix + init_load(); +/* init_unixsys(); */ +#endif unix + init_array(); +/* init_list(); */ +/* init_predicate(); */ +/* init_cfun(); */ +/* init_sequence(); */ +/* init_structure(); */ +/* init_string(); */ +#if !defined(GBC_BOEHM) + init_alloc_function(); +#endif +#ifdef TCP +/* init_tcp(); */ +#endif TCP +#ifdef THREADS + init_lwp(); +#endif THREADS +#ifdef CLOS +/* init_instance(); */ + init_clos(); +/* init_gfun(); */ +#endif CLOS +#ifdef TK + init_tk(); +#endif TK +#ifdef LOCATIVE + init_unify(); +#endif LOCATIVE +/* init_hash(); */ +#ifdef unix +/* init_unixfsys(); */ + init_unixtime(); +#endif unix + init_compiler(); + init_interpreter(); + init_eval(); +/* init_lex(); */ +/* init_reference(); */ + init_assignment(); +/* init_stacks(); */ + init_error(); +/* init_toplevel(); */ +/* init_conditional(); */ +/* init_catch(); */ + init_macros(); +/* init_let(); */ +/* init_prog(); */ +/* init_block(); */ + init_multival(); +/* init_mapfun(); */ +/* init_iteration(); */ + init_cmpaux(); + init_main(); + init_format(); + init_interrupt(); +#ifdef RUNTIME + SYM_VAL(Vfeatures) = CONS(make_keyword("RUNTIME"), SYM_VAL(Vfeatures)); +#endif + init_lisp_libs(); +} diff --git a/src/c/instance.d b/src/c/instance.d new file mode 100644 index 000000000..8785622b2 --- /dev/null +++ b/src/c/instance.d @@ -0,0 +1,167 @@ +/* + instance.c -- CLOS interface. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +cl_object Sprint_object; + +/******************************* ------- ******************************/ + +cl_object +allocate_instance(cl_object class, int size) +{ + cl_object x = alloc_instance(size); + int i; + x->instance.class = class; + for (i = 0; i < size; i++) + x->instance.slots[i] = OBJNULL; + return(x); +} + +@(defun si::allocate_instance (class size) +@ + if (type_of(class) != t_instance) + FEwrong_type_argument(Sinstance, class); + + @(return allocate_instance(class, fixnnint(size))) +@) + +/* corr is a list of (newi . oldi) describing which of the new slots + retains a value from an old slot + */ +@(defun si::change_instance (x class size corr) + int nslot, i; + cl_object * oldslots; +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + + if (type_of(class) != t_instance) + FEwrong_type_argument(Sinstance, class); + + nslot = fixnnint(size); + x->instance.class = class; + x->instance.length = nslot; + oldslots = x->instance.slots; + x->instance.slots = alloc_align(sizeof(cl_object)*nslot,sizeof(cl_object)); + for (i = 0; i < nslot; i++) { + if (!Null(corr) && fix(CAAR(corr)) == i) { + x->instance.slots[i] = oldslots[fix(CDAR(corr))]; + corr = CDR(corr); + } + else + x->instance.slots[i] = OBJNULL; + } + @(return) /* FIXME! Is this what we need? */ +@) + +@(defun si::instance_class (x) +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + @(return x->instance.class) +@) + +@(defun si::instance_class_set (x y) +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (type_of(y) != t_instance) + FEwrong_type_argument(Sinstance, y); + x->instance.class = y; + @(return x) +@) + +cl_object +instance_ref(cl_object x, int i) +{ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (i >= x->instance.length || i < 0) + FEerror("~S is an illegal slot index1.",1,i); + return(x->instance.slots[i]); +} + +@(defun si::instance_ref (x index) + cl_fixnum i; +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (!FIXNUMP(index) || + (i = fix(index)) < 0 || i >= x->instance.length) + FEerror("~S is an illegal slot index.", 1, index); + @(return x->instance.slots[i]) +@) + +@(defun si::instance_ref_safe (x index) + cl_fixnum i; +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (!FIXNUMP(index) || + (i = fix(index)) < 0 || i >= x->instance.length) + FEerror("~S is an illegal slot index.", 1, index); + x = x->instance.slots[i]; + if (x == OBJNULL) + FEerror("Slot index ~S unbound", 1, index); + @(return x->instance.slots[i]) +@) + +cl_object +instance_set(cl_object x, int i, cl_object v) +{ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (i >= x->instance.length || i < 0) + FEerror("~S is an illegal slot index2.", 1, i); + x->instance.slots[i] = v; + return(v); +} + +@(defun si::instance_set (x index value) + cl_fixnum i; +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (!FIXNUMP(index) || + (i = fix(index)) >= x->instance.length || i < 0) + FEerror("~S is an illegal slot index.", 1, index); + x->instance.slots[i] = value; + @(return value) +@) + +@(defun si::instancep (x) +@ + @(return ((type_of(x) == t_instance) ? Ct : Cnil)) +@) + +@(defun si::sl_boundp (x) +@ + @(return ((x == OBJNULL) ? Cnil : Ct)) +@) + +@(defun si::sl_makunbound (x index) + cl_fixnum i; +@ + if (type_of(x) != t_instance) + FEwrong_type_argument(Sinstance, x); + if (!FIXNUMP(index) || + (i = fix(index)) >= x->instance.length || i < 0) + FEerror("~S is an illegal slot index.", 1, index); + x->instance.slots[i] = OBJNULL; + @(return x) +@) diff --git a/src/c/interpreter.d b/src/c/interpreter.d new file mode 100644 index 000000000..3d0cd91db --- /dev/null +++ b/src/c/interpreter.d @@ -0,0 +1,881 @@ +/* + interpreter.c -- Bytecode interpreter. +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +#define next_code(v) *(v++) +#undef frs_pop +#define frs_pop() { stack->vector.fillp = frs_top->frs_sp; frs_top--; } + +static void +lambda_bind_var(cl_object var, cl_object val, cl_object specials) +{ + if (!member_eq(var, specials)) + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); + else { + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); + } +} + +static void +bind_var(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); +} + +static void +bind_special(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); +} + +static cl_object * +lambda_bind(int narg, cl_object lambda_list, cl_object *args) +{ + cl_object *data = &lambda_list->bytecodes.data[2]; + cl_object specials = lambda_list->bytecodes.data[1]; + cl_object aux; + int i, n; + bool other_keys = FALSE; + bool check_remaining = TRUE; + bool allow_other_keys_found = FALSE; + + /* 1) REQUIRED ARGUMENTS: N var1 ... varN */ + n = fix(next_code(data)); + if (narg < n) + check_arg_failed(narg, n); + for (; n; n--, narg--) + lambda_bind_var(next_code(data), next_code(args), specials); + + /* 2) OPTIONAL ARGUMENTS: N var1 value1 flag1 ... varN valueN flagN */ + for (n = fix(next_code(data)); n; n--, data+=3) { + if (narg) { + lambda_bind_var(data[0], args[0], specials); + args++; narg--; + if (!Null(data[2])) + lambda_bind_var(data[2], Ct, specials); + } else { + cl_object defaults = data[1]; + if (FIXNUMP(defaults)) { + interpret(&data[1] + fix(defaults)); + defaults = VALUES(0); + } + lambda_bind_var(data[0], defaults, specials); + if (!Null(data[2])) + lambda_bind_var(data[2], Cnil, specials); + } + } + + /* 3) REST ARGUMENT: {rest-var | NIL} */ + if (!Null(data[0])) { + cl_object rest = Cnil; + check_remaining = FALSE; + for (i=narg; i; ) + rest = CONS(args[--i], rest); + lambda_bind_var(data[0], rest, specials); + } + data++; + + /* 4) ALLOW-OTHER-KEYS: { T | NIL } */ + other_keys = !Null(next_code(data)); + + /* 5) KEYWORDS: N key1 var1 value1 flag1 ... keyN varN valueN flagN */ + n = fix(next_code(data)); + if (n != 0 || other_keys) { + cl_object *keys; + cl_object spp[n]; + bool other_found = FALSE; + for (i=0; ibytecodes.data[0]); + for (i=0; ibytecodes.data[0]); + + return &data[2]; +} + +cl_object +lambda_apply(int narg, cl_object fun, cl_object *args) +{ cl_object lex_old = lex_env; + cl_object output, name, *body; + bds_ptr old_bds_top; + volatile bool block, closure; + + if (type_of(fun) != t_bytecodes) + FEinvalid_function(fun); + + /* Set the lexical environment of the function */ + ihs_check; + if (Null(fun->bytecodes.lex)) + lex_env = CONS(Cnil, Cnil); + else + lex_env = CONS(CAR(fun->bytecodes.lex),CDR(fun->bytecodes.lex)); + ihs_push(fun, lex_env); + old_bds_top = bds_top; + + /* Establish bindings */ + body = lambda_bind(narg, fun, args); + + /* If it is a named lambda, set a block for RETURN-FROM */ + block = FALSE; + name = fun->bytecodes.data[0]; + if (Null(fun->bytecodes.data[0])) + block = FALSE; + else { + block = TRUE; + fun = new_frame_id(); + lex_block_bind(name, fun); + if (frs_push(FRS_CATCH, fun)) { + output = VALUES(0); + goto END; + } + } + + /* Process statements */ + VALUES(0) = Cnil; + NValues = 0; + interpret(body); + +END: if (block) frs_pop(); + bds_unwind(old_bds_top); + lex_env = lex_old; + ihs_pop(); + returnn(VALUES(0)); +} + + +/* ----------------- BYTECODE STACK --------------- */ + +cl_object stack = OBJNULL; + +static void +stack_grow(void) { + cl_object *old_data = stack->vector.self.t; + cl_index old_size = stack->vector.fillp; + stack->vector.dim += 128; + array_allocself(stack); + memcpy(stack->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +push1(register cl_object op) { + cl_index where; + where = stack->vector.fillp; + if (where >= stack->vector.dim) + stack_grow(); + stack->vector.self.t[where] = op; + stack->vector.fillp++; +} + +static cl_object +pop1() { + return stack->vector.self.t[--stack->vector.fillp]; +} + +static cl_index +get_sp_index() { + return stack->vector.fillp; +} + +static void +dec_sp_index(register cl_index delta) { + stack->vector.fillp -= delta; +} + +static void +set_sp_index(register cl_index sp) { + if (stack->vector.fillp < sp) + FEerror("Tried to advance stack", 0); + stack->vector.fillp = sp; +} + +static cl_object * +get_sp() { + return stack->vector.self.t + stack->vector.fillp; +} + +static cl_object * +get_sp_at(cl_index where) { + return stack->vector.self.t + where; +} + +/* -------------------- AIDS TO THE INTERPRETER -------------------- */ + +static inline cl_fixnum +get_oparg(cl_object o) { + return GET_OPARG(o); +} + +static inline cl_object * +packed_label(cl_object *v) { + return v + GET_OPARG(v[0]); +} + +static inline cl_object * +simple_label(cl_object *v) { + return v + fix(v[0]); +} + +static cl_object +search_symbol_function(register cl_object fun) { + cl_object output = lex_fun_sch(fun); + if (!Null(output)) + return output; + output = SYM_FUN(fun); + if (output == OBJNULL || fun->symbol.mflag) + FEundefined_function(fun); + return output; +} + +static cl_object +search_symbol_value(register cl_object s) { + cl_object x; + /* x = lex_var_sch(form); */ + for (x = CAR(lex_env); CONSP(x); x = CDR(x)) + if (CAAR(x) == s) { + x = CDAR(x); + if (ENDP(x)) break; + return CAR(x); + } + x = SYM_VAL(s); + if (x == OBJNULL) + FEunbound_variable(s); + return x; +} + +static cl_object +interpret_apply(int narg, cl_object fun, cl_object *args) { + cl_object x; + + AGAIN: + switch (type_of(fun)) { + case t_cfun: + ihs_push_funcall(fun->cfun.name); + x = APPLY(narg, fun->cfun.entry, args); + ihs_pop(); + return x; + case t_cclosure: + /* FIXME! Shouldn't we register this call somehow? */ + return APPLY_closure(narg, fun->cclosure.entry, fun->cclosure.env, args); +#ifdef CLOS + case t_gfun: + ihs_push_funcall(fun->gfun.name); + x = gcall(narg, fun, args); + ihs_pop(); + return x; +#endif + case t_bytecodes: + return lambda_apply(narg, fun, args); + case t_symbol: + fun = search_symbol_function(fun); + goto AGAIN; + default: + } + FEinvalid_function(fun); +} + +/* -------------------- THE INTERPRETER -------------------- */ + +static cl_object * +interpret_block(cl_object *vector) { + cl_object * volatile exit, name; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + lex_copy(); + + exit = packed_label(vector - 1); + lex_block_bind(next_code(vector), id); + if (frs_push(FRS_CATCH,id) == 0) + vector = interpret(vector); + frs_pop(); + lex_env = lex_old; + return exit; +} + +static cl_object * +interpret_catch(cl_object *vector) { + cl_object * volatile exit; + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,VALUES(0)) == 0) + interpret(vector); + frs_pop(); + return exit; +} + +static cl_object * +interpret_tagbody(cl_object *vector) { + cl_index i, ntags = get_oparg(vector[-1]); + cl_object lex_old = lex_env; + cl_object id = new_frame_id(); + cl_object *aux, *tag_list = vector; + + lex_copy(); + aux = vector; + for (i=0; i= ntags) + FEerror("Internal error: TAGBODY id used for RETURN-FROM.",0); + else + aux = simple_label(aux); + } + vector = interpret(aux); + frs_pop(); + lex_env = lex_old; + VALUES(0) = Cnil; + NValues = 0; + return vector; +} + +static cl_object * +interpret_unwind_protect(cl_object *vector) { + bool unwinding; + int nr; + cl_object * volatile exit; + + exit = packed_label(vector-1); + if (frs_push(FRS_PROTECT, Cnil)) + unwinding = TRUE; + else { + interpret(vector); + unwinding = FALSE; + } + frs_pop(); + nr = NValues; + MV_SAVE(nr); + exit = interpret(exit); + MV_RESTORE(nr); + if (unwinding) + unwind(nlj_fr, nlj_tag); + return exit; +} + +static cl_object * +interpret_do(cl_object *vector) { + cl_object *volatile exit; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + exit = packed_label(vector-1); + if (frs_push(FRS_CATCH,id) == 0) + interpret(vector); + frs_pop(); + + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dolist(cl_object *vector) { + cl_object *output, *volatile exit; + cl_object list, var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + list = VALUES(0); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Build list & bind variable*/ + vector = interpret(vector); + output = packed_label(vector-1); + while (!endp(list)) { + NValues = 1; + VALUES(0) = CAR(list); + interpret(vector); + list = CDR(list); + } + VALUES(0) = Cnil; + NValues = 1; + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dotimes(cl_object *vector) { + cl_object *output, *volatile exit; + cl_fixnum length, i; + cl_object var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + length = fix(VALUES(0)); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Bind variable */ + vector = interpret(vector); + output = packed_label(vector-1); + for (i = 0; i < length;) { + interpret(vector); + NValues = 1; + VALUES(0) = MAKE_FIXNUM(++i); + } + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object +close_around(cl_object fun, cl_object lex) { + cl_object v = alloc_object(t_bytecodes); + v->bytecodes.size = fun->bytecodes.size; + v->bytecodes.data = fun->bytecodes.data; + if (!Null(CAR(lex)) || !Null(CDR(lex))) + v->bytecodes.lex = CONS(CAR(lex),CDR(lex)); + else + v->bytecodes.lex = Cnil; + return v; +} + +static cl_object * +interpret_flet(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index nfun = get_oparg(vector[-1]); + + lex_copy(); + while (nfun--) { + cl_object fun = next_code(vector); + cl_object f = close_around(fun,lex_old); + lex_fun_bind(f->bytecodes.data[0], f); + } + vector = interpret(vector); + lex_env = lex_old; + return vector; +} + +static cl_object * +interpret_labels(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index i, nfun = get_oparg(vector[-1]); + cl_object l; + + lex_copy(); + for (i=0; ibytecodes.data[0], f); + } + /* Update the closures so that all functions can call each other */ + for (i=0, l=CDR(lex_env); isymbol.stype == stp_constant) + FEassignment_to_constant(var); + else + SYM_VAL(var) = value; + } + } + if (NValues > 1) NValues = 1; + return vector; +} + +static cl_object * +interpret_progv(cl_object *vector) { + cl_object values = VALUES(0); + cl_object vars = pop1(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + while (!endp(vars)) { + if (values == Cnil) + bds_bind(CAR(vars), OBJNULL); + else { + bds_bind(CAR(vars), car(values)); + values = CDR(values); + } + vars = CDR(vars); + } + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +static cl_object * +interpret_pushenv(cl_object *vector) { + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +cl_object * +interpret(cl_object *vector) { + enum cl_type t; + cl_object s; + cl_fixnum n; + + BEGIN: + s = next_code(vector); + t = type_of(s); + if (t == t_symbol) { + VALUES(0) = search_symbol_value(s); + NValues = 1; + goto BEGIN; + } + if (t != t_fixnum) { + VALUES(0) = s; + NValues = 1; + goto BEGIN; + } + switch (GET_OP(s)) { + case OP_PUSHQ: + push1(next_code(vector)); + break; + case OP_PUSH: + push1(VALUES(0)); + break; + case OP_PUSHV: + push1(search_symbol_value(next_code(vector))); + break; + case OP_QUOTE: + VALUES(0) = next_code(vector); + NValues = 1; + break; + case OP_NOP: + VALUES(0) = Cnil; + NValues = 0; + break; + case OP_BLOCK: + vector = interpret_block(vector); + break; + case OP_PUSHVALUES: { + int i; + for (i=0; isymbol.stype == stp_constant) + FEassignment_to_constant(var); + else + SYM_VAL(var) = VALUES(0); + break; + } + case OP_PBIND: + bind_var(next_code(vector), pop1()); + break; + case OP_PBINDS: + bind_special(next_code(vector), pop1()); + break; + case OP_PSETQ: + CADR(lex_var_sch(next_code(vector))) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + case OP_PSETQS: { + cl_object var = next_code(vector); + if (var->symbol.stype == stp_constant) + FEassignment_to_constant(var); + else + SYM_VAL(var) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + } + case OP_MSETQ: + vector = interpret_msetq(vector); + break; + case OP_MBIND: + vector = interpret_mbind(vector); + break; + case OP_MPROG1: + vector = interpret_mprog1(vector); + break; + case OP_PROGV: + vector = interpret_progv(vector); + break; + case OP_PUSHENV: + vector = interpret_pushenv(vector); + break; + case OP_VALUES: { + cl_fixnum n = get_oparg(s); + NValues = n; + while (n) + VALUES(--n) = pop1(); + break; + } + case OP_NTHVAL: { + cl_index n = fix(pop1()); + if (n < 0 || n >= NValues) + VALUES(0) = Cnil; + else + VALUES(0) = VALUES(n); + NValues = 1; + break; + } + case OP_DOLIST: + vector = interpret_dolist(vector); + break; + case OP_DOTIMES: + vector = interpret_dotimes(vector); + break; + case OP_DO: + vector = interpret_do(vector); + break; + case OP_TAGBODY: + vector = interpret_tagbody(vector); + break; + case OP_UNWIND: + vector = interpret_unwind_protect(vector); + break; + default: + FEerror("Internal error: Unknown code ~S", + 1, MAKE_FIXNUM(*(vector-1))); + } + goto BEGIN; +} + +@(defun si::interpreter_stack () +@ + @(return stack) +@) + +void +init_interpreter(void) +{ + register_root(&stack); + stack = alloc_simple_vector(128, aet_object); + array_allocself(stack); + stack->vector.hasfillp = TRUE; + stack->vector.fillp = 0; +} diff --git a/src/c/lex.d b/src/c/lex.d new file mode 100644 index 000000000..5c05c3b6b --- /dev/null +++ b/src/c/lex.d @@ -0,0 +1,77 @@ +/* + lex.c -- Lexical environment. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******** EXPORTS ********/ + +#ifndef THREADS +cl_object lex_env = OBJNULL; +#endif + +cl_object siSsymbol_macro; +cl_object Smacro; +cl_object Sblock; +cl_object Stag; + +/******** ------- ********/ + +void +lex_fun_bind(cl_object name, cl_object fun) +{ + CDR(lex_env) = CONS(list(3, name, Sfunction, fun), CDR(lex_env)); +} + +void +lex_symbol_macro_bind(cl_object name, cl_object exp_fun) +{ + CAR(lex_env) = CONS(list(3, name, siSsymbol_macro, exp_fun), CAR(lex_env)); +} + +void +lex_macro_bind(cl_object name, cl_object exp_fun) +{ + CDR(lex_env) = CONS(list(3, name, Smacro, exp_fun), CDR(lex_env)); +} + +void +lex_tag_bind(cl_object tag, cl_object id) +{ + CDR(lex_env) = CONS(list(3, tag, Stag, id), CDR(lex_env)); +} + +void +lex_block_bind(cl_object name, cl_object id) +{ + CDR(lex_env) = CONS(list(3, name, Sblock, id), CDR(lex_env)); +} + +cl_object +lex_sch(cl_object alist, cl_object name, cl_object type) +{ + while (!endp(alist)) { + if (CAAR(alist) == name && CADAR(alist) == type) + return(CADDAR(alist)); + alist = CDR(alist); + } + return(Cnil); +} + +@(defun si::lex_env () +@ + @(return lex_env) +@) diff --git a/src/c/list.d b/src/c/list.d new file mode 100644 index 000000000..5e8d7d8b5 --- /dev/null +++ b/src/c/list.d @@ -0,0 +1,1013 @@ +/* + list.d -- List manipulating routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +/******************************* EXPORTS ******************************/ + +cl_object Ktest; +cl_object Ktest_not; +cl_object Kkey; +cl_object Kinitial_element; + +/******************************* ------- ******************************/ + +#ifdef THREADS +#define test_function clwp->lwp_test_function +#define item_compared clwp->lwp_item_compared +#define tf clwp->lwp_tf +#define key_function clwp->lwp_key_function +#define kf clwp->lwp_kf +#else +static cl_object test_function; +static cl_object item_compared; +static bool (*tf)(); +static cl_object key_function; +static cl_object (*kf)(); +#endif THREADS + +#define TEST(x) (*tf)(x) + +#define saveTEST \ + cl_object old_test_function = test_function; \ + cl_object old_item_compared = item_compared; \ + bool (*old_tf)() = tf; \ + cl_object old_key_function = key_function; \ + cl_object (*old_kf)() = kf; \ + volatile bool eflag = FALSE + +#define protectTEST \ + if (frs_push(FRS_PROTECT, Cnil)) { \ + eflag = TRUE; \ + goto L; \ + } + +#define restoreTEST \ +L: \ + frs_pop(); \ + test_function = old_test_function; \ + item_compared = old_item_compared; \ + tf = old_tf; \ + key_function = old_key_function; \ + kf = old_kf; \ + if (eflag) unwind(nlj_fr, nlj_tag); + +static bool +test_compare(cl_object x) +{ + cl_object test = _funcall(3, test_function, item_compared, (*kf)(x)); + return (test != Cnil); +} + +static bool +test_compare_not(cl_object x) +{ + cl_object test = _funcall(3, test_function, item_compared, (*kf)(x)); + return (test == Cnil); +} + +static bool +test_eql(cl_object x) +{ + return(eql(item_compared, (*kf)(x))); +} + +static cl_object +apply_key_function(cl_object x) +{ + return _funcall(2, key_function, x); +} + +cl_object +identity(cl_object x) +{ + return(x); +} + +static void +setupTEST(cl_object item, cl_object test, cl_object test_not, cl_object key) +{ + item_compared = item; + if (test != Cnil) { + if (test_not != Cnil) + FEerror("Both :TEST and :TEST-NOT are specified.", 0); + test_function = test; + tf = test_compare; + } else if (test_not != Cnil) { + test_function = test_not; + tf = test_compare_not; + } else + tf = test_eql; + if (key != Cnil) { + key_function = key; + kf = apply_key_function; + } else + kf = identity; +} + +#define PREDICATE2(f) \ +cl_return f ## _if(int narg, cl_object pred, cl_object arg, cl_object key, cl_object val) \ +{ \ + if (narg < 2) \ + FEtoo_few_arguments(&narg); \ + return f(narg+2, pred, arg, Ktest, Sfuncall, key, val); \ +} \ +\ +cl_return f ## _if_not(int narg, cl_object pred, cl_object arg, cl_object key, cl_object val) \ +{ \ + if (narg < 2) \ + FEtoo_few_arguments(&narg); \ + return f(narg+2, pred, arg, Ktest_not, Sfuncall, key, val); \ +} + +#define PREDICATE3(f) \ +cl_return f ## _if(int narg, cl_object arg1, cl_object pred, cl_object arg3, cl_object key, cl_object val) \ +{ \ + if (narg < 3) \ + FEtoo_few_arguments(&narg); \ + return f(narg+2, arg1, pred, arg3, Ktest, Sfuncall, key, val); \ +} \ +\ +cl_return f ## _if_not(int narg, cl_object arg1, cl_object pred, cl_object arg3, cl_object key, \ + cl_object val) \ +{ \ + if (narg < 3) \ + FEtoo_few_arguments(&narg); \ + return f(narg+2, arg1, pred, arg3, Ktest_not, Sfuncall, key, val); \ +} + +@(defun car (x) +@ + if (Null(x)) + @(return Cnil) + if (ATOM(x)) + FEtype_error_list(x); + @(return CAR(x)) +@) + +cl_object +car(cl_object x) +{ + if (Null(x)) + return(x); + if (CONSP(x)) + return(CAR(x)); + FEtype_error_list(x); +} + +@(defun cdr (x) +@ + if (Null(x)) + @(return Cnil) + if (ATOM(x)) + FEtype_error_list(x); + @(return CDR(x)) +@) + +cl_object +cdr(cl_object x) +{ + if (Null(x)) + return(x); + if (CONSP(x)) + return(CDR(x)); + FEtype_error_list(x); +} + +@(defun list (&rest args) + cl_object list = Cnil, z; +@ + if (narg-- != 0) { + list = z = CONS(va_arg(args, cl_object), Cnil); + while (narg-- > 0) + z = CDR(z) = CONS(va_arg(args, cl_object), Cnil); + } + @(return list) +@) + +cl_object +list(int narg, ...) +{ + cl_object p = Cnil, *z = &p; + va_list args; + + va_start(args, narg); + while (narg-- > 0) + z = &CDR(*z = CONS(va_arg(args, cl_object), Cnil)); + return(p); +} + +@(defun listA (&rest args) + cl_object p = Cnil, *z=&p; +@ + if (narg == 0) + FEtoo_few_arguments(&narg); + while (--narg > 0) + z = &CDR( *z = CONS(va_arg(args, cl_object), Cnil)); + *z = va_arg(args, cl_object); + @(return p) +@) + +cl_object +listA(int narg, ...) +{ + cl_object p = Cnil, *z = &p; + va_list args; + + va_start(args, narg); + while (--narg > 0) + z = &CDR( *z = CONS(va_arg(args, cl_object), Cnil)); + *z = va_arg(args, cl_object); + return(p); +} + +static void +copy_list_to(cl_object x, cl_object **z) +{ + cl_object *y; + + y = *z; + loop_for_in(x) { + y = &CDR(*y = CONS(CAR(x), Cnil)); + } end_loop_for_in; + *z = y; +} + +@(defun append (&rest rest) + cl_object x, *lastcdr; +@ + if (narg == 0) + x = Cnil; + else { + lastcdr = &x; + va_start(rest, narg); + while (narg-- > 1) + copy_list_to(va_arg(rest, cl_object), &lastcdr); + *lastcdr = va_arg(rest, cl_object); + } + @(return x) +@) + +cl_object +append(cl_object x, cl_object y) +{ + cl_object w, *z; + + z = &w; + copy_list_to(x, &z); + *z = y; + return(w); +} + +#if 1 +/* Open coded CARs and CDRs */ +#define car(foo) \ + (void)foo; \ + if (x != Cnil) { \ + if (CONSP(x)) \ + x = x->cons.car; \ + else \ + goto E; \ + } +#define cdr(foo) \ + (void)foo; \ + if (x != Cnil) { \ + if (CONSP(x)) \ + x = x->cons.cdr; \ + else \ + goto E; \ + } +#define defcxr(name, arg, code) \ +cl_object name(cl_object foo) { \ + cl_object arg = foo; \ + code; return x; \ +E: FEtype_error_list(arg);} \ +cl_return L##name(int narg, cl_object arg) { \ + check_arg(1); \ + return1(name(arg)); \ +} +#else +#define defcxr(name, arg, code) \ +cl_object name(cl_object arg) { return code; } \ +cl_return L##name(int narg, cl_object arg) { \ + check_arg(1); \ + return1(name(arg)); \ +} +#endif + +defcxr(caar, x, car(car(x))) +defcxr(cadr, x, car(cdr(x))) +defcxr(cdar, x, cdr(car(x))) +defcxr(cddr, x, cdr(cdr(x))) +defcxr(caaar, x, car(car(car(x)))) +defcxr(caadr, x, car(car(cdr(x)))) +defcxr(cadar, x, car(cdr(car(x)))) +defcxr(caddr, x, car(cdr(cdr(x)))) +defcxr(cdaar, x, cdr(car(car(x)))) +defcxr(cdadr, x, cdr(car(cdr(x)))) +defcxr(cddar, x, cdr(cdr(car(x)))) +defcxr(cdddr, x, cdr(cdr(cdr(x)))) +defcxr(caaaar, x, car(car(car(car(x))))) +defcxr(caaadr, x, car(car(car(cdr(x))))) +defcxr(caadar, x, car(car(cdr(car(x))))) +defcxr(caaddr, x, car(car(cdr(cdr(x))))) +defcxr(cadaar, x, car(cdr(car(car(x))))) +defcxr(cadadr, x, car(cdr(car(cdr(x))))) +defcxr(caddar, x, car(cdr(cdr(car(x))))) +defcxr(cadddr, x, car(cdr(cdr(cdr(x))))) +defcxr(cdaaar, x, cdr(car(car(car(x))))) +defcxr(cdaadr, x, cdr(car(car(cdr(x))))) +defcxr(cdadar, x, cdr(car(cdr(car(x))))) +defcxr(cdaddr, x, cdr(car(cdr(cdr(x))))) +defcxr(cddaar, x, cdr(cdr(car(car(x))))) +defcxr(cddadr, x, cdr(cdr(car(cdr(x))))) +defcxr(cdddar, x, cdr(cdr(cdr(car(x))))) +defcxr(cddddr, x, cdr(cdr(cdr(cdr(x))))) +#undef car +#undef cdr + +#define LENTH(n) (int narg, cl_object x) {\ + check_arg(1);\ + return1(nth(n, x));\ +} +cl_return Lfifth LENTH(4) +cl_return Lsixth LENTH(5) +cl_return Lseventh LENTH(6) +cl_return Leighth LENTH(7) +cl_return Lninth LENTH(8) +cl_return Ltenth LENTH(9) +#undef LENTH + +@(defun cons (car cdr) +@ + @(return CONS(car, cdr)) +@) + +static bool +tree_equal(cl_object x, cl_object y) +{ + cs_check(x); + +BEGIN: + if (CONSP(x)) + if (CONSP(y)) + if (tree_equal(CAR(x), CAR(y))) { + x = CDR(x); + y = CDR(y); + goto BEGIN; + } else + return(FALSE); + else + return(FALSE); + else { + item_compared = x; + if (TEST(y)) + return(TRUE); + else + return(FALSE); + } +} + +@(defun tree_equal (x y &key test test_not) +@ + setupTEST(Cnil, test, test_not, Cnil); + if (tree_equal(x, y)) + @(return Ct) + else + @(return Cnil) +@) + +@(defun endp (x) +@ + if (Null(x)) + @(return Ct) + if (CONSP(x)) + @(return Cnil) + FEtype_error_list(x); +@) + +bool +endp1(cl_object x) +{ + if (CONSP(x)) + return(FALSE); + if (Null(x)) + return(TRUE); + FEtype_error_list(x); +} + +cl_object +list_length(cl_object x) +{ + cl_fixnum n; + cl_object fast, slow; + + /* INV: A list's length always fits in a fixnum */ + fast = slow = x; + for (n = 0; CONSP(fast); n++, fast = CDR(fast)) { + if (n & 1) { + /* Circular list? */ + if (slow == fast) return Cnil; + slow = CDR(slow); + } + } + if (fast != Cnil) + FEtype_error_proper_list(x); + return MAKE_FIXNUM(n); +} + +@(defun list_length (x) +@ + @(return list_length(x)) +@) + +@(defun nth (n x) +@ + @(return nth(fixint(n), x)) +@) + +cl_object +nth(cl_fixnum n, cl_object x) +{ + if (n < 0) + FEtype_error_index(MAKE_FIXNUM(n)); + /* INV: No need to check for circularity since we visit + at most `n' conses */ + for (; n > 0 && CONSP(x); n--) + x = CDR(x); + if (x == Cnil) + return Cnil; + if (CONSP(x)) + return CAR(x); + FEtype_error_list(x); +} + +@(defun nthcdr (n x) +@ + @(return nthcdr(fixint(n), x)) +@) + +cl_object +nthcdr(cl_fixnum n, cl_object x) +{ + if (n < 0) + FEtype_error_index(MAKE_FIXNUM(n)); + while (n-- > 0 && !ENDP(x)) + x = CDR(x); + return(x); +} + +@(defun last (l &optional (k MAKE_FIXNUM(1))) + cl_object r; + cl_fixnum n; +@ + n = fixnnint(k); + r = l; + loop_for_on(l) { + if (n) n--; else r = CDR(r); + } end_loop_for_on; + @(return r) +@) + +@(defun make_list (size &key initial_element &aux x) + cl_fixnum i; +@ + if (!FIXNUMP(size)) + FEerror("Cannot make a list of the size ~D.", 1, size); + i = fixnnint(size); + while (i-- > 0) + x = CONS(initial_element, x); + @(return x) +@) + +@(defun copy_list (x) +@ + @(return copy_list(x)) +@) + +/* + Copy_list(x) copies list x. +*/ +cl_object +copy_list(cl_object x) +{ + cl_object copy; + cl_object *y = © + + loop_for_on(x) { + y = &CDR(*y = CONS(CAR(x), Cnil)); + } end_loop_for_on; + *y = x; + return copy; +} + +@(defun copy_alist (x) +@ + @(return copy_alist(x)) +@) + +/* + Copy_alist(x) copies alist x. +*/ +cl_object +copy_alist(cl_object x) +{ + cl_object copy; + cl_object *y = © + + loop_for_on(x) { + cl_object pair = CAR(x); + if (ATOM(pair)) + FEtype_error_alist(x); + *y = CONS(CONS(CAR(pair), CDR(pair)), Cnil); + y = &CDR(*y); + } end_loop_for_on; + *y = x; + return copy; +} + +@(defun copy_tree (x) +@ + @(return copy_tree(x)) +@) + +/* + Copy_tree(x) returns a copy of tree x. +*/ +cl_object +copy_tree(cl_object x) +{ + cs_check(x); + if (ATOM(x)) + return x; + return CONS(copy_tree(CAR(x)), copy_tree(CDR(x))); +} + +@(defun revappend (x y) +@ + loop_for_in(x) { + y = CONS(CAR(x),y); + } end_loop_for_in; + @(return y) +@) + +@(defun nconc (&rest lists) + cl_object x, l,*lastcdr; +@ + if (narg < 1) + @(return Cnil) + lastcdr = &x; + while (narg-- > 1) { + *lastcdr = l = va_arg(lists, cl_object); + loop_for_on(l) { + lastcdr = &CDR(l); + } end_loop_for_on; + } + *lastcdr = va_arg(lists, cl_object); + @(return x) +@) + +cl_object +nconc(cl_object l, cl_object y) +{ + cl_object x = l, x1; + + if (x == Cnil) + return y; + /* INV: This loop is run at least once */ + loop_for_on(x) { + x1 = x; + } end_loop_for_on; + CDR(x1) = y; + return l; +} + +@(defun reconc (l y) + cl_object x, z; +@ + /* INV: when a circular list is "reconc'ed", the pointer ends + up at the beginning of the original list, hence we need no + slow pointer */ + for (x = l; CONSP(x); ) { + z = x; + x = CDR(x); + if (x == l) FEcircular_list(l); + CDR(z) = y; + y = z; + } + if (x != Cnil) + FEtype_error_proper_list(l); + @(return y) +@) + +/* CONTINUE HERE!!!! */ +@(defun butlast (lis &optional (nn MAKE_FIXNUM(1))) + cl_object r, res = Cnil, *fill = &res; + cl_fixnum delay; +@ + /* INV: No list has more than MOST_POSITIVE_FIX elements */ + if (!FIXNUMP(nn)) + @(return Cnil) + delay = fixnnint(nn); + r = lis; + loop_for_on(lis) { + if (delay) + delay--; + else { + fill = &CDR(*fill = CONS(CAR(r), Cnil)); + r = CDR(r); + } + } end_loop_for_on; + @(return res) +@) + +@(defun nbutlast (lis &optional (nn MAKE_FIXNUM(1))) + cl_fixnum delay; + cl_object x, r; +@ + /* INV: No list has more than MOST_POSITIVE_FIX elements */ + if (!FIXNUMP(nn)) + @(return Cnil) + /* We add 1 because at the end `r' must point to the + cons that must be modified */ + delay = fixnnint(nn)+1; + r = x = lis; + loop_for_on(x) { + if (delay) delay--; else r = CDR(r); + } end_loop_for_on; + if (delay > 0) + /* nn > length(lis) */ + lis = Cnil; + else + CDR(r) = Cnil; + @(return lis) +@) + +@(defun ldiff (x y) + cl_object res = Cnil, *fill = &res; +@ + loop_for_on(x) { + if (x == y) + break; + else + fill = &CDR(*fill = CONS(CAR(x), Cnil)); + } end_loop_for_on; + @(return res) +@) + +@(defun rplaca (x v) +@ + assert_type_cons(x); + CAR(x) = v; + @(return x) +@) + +@(defun rplacd (x v) +@ + assert_type_cons(x); + CDR(x) = v; + @(return x) +@) + +@(defun subst (new old tree &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(old, test, test_not, key); + tree = subst(new, tree); + restoreTEST; + @(return tree) +@) + + +/* + Subst(new, tree) returns + the result of substituting new in tree. +*/ +cl_object +subst(cl_object new, cl_object tree) +{ + cs_check(new); + + if (TEST(tree)) + return(new); + else if (CONSP(tree)) + return(CONS(subst(new, CAR(tree)), subst(new, CDR(tree)))); + else + return(tree); +} + +PREDICATE3(Lsubst) + +@(defun nsubst (new old tree &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(old, test, test_not, key); + nsubst(new, &tree); + restoreTEST; + @(return tree) +@) + +/* + Nsubst(new, treep) stores + the result of nsubstituting new in *treep + to *treep. +*/ +void +nsubst(cl_object new, cl_object *treep) +{ + cs_check(new); + + if (TEST(*treep)) + *treep = new; + else if (CONSP(*treep)) { + nsubst(new, &CAR(*treep)); + nsubst(new, &CDR(*treep)); + } +} + +PREDICATE3(Lnsubst) + +@(defun sublis (alist tree &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(Cnil, test, test_not, key); + tree = sublis(alist, tree); + restoreTEST; + @(return tree) +@) + +/* + Sublis(alist, tree) returns + result of substituting tree by alist. +*/ +cl_object +sublis(cl_object alist, cl_object tree) +{ + cl_object x = alist; + + cs_check(alist); + loop_for_in(x) { + item_compared = car(CAR(x)); + if (TEST(tree)) return(cdr(CAR(x))); + } end_loop_for_in; + if (CONSP(tree)) + return(CONS(sublis(alist, CAR(tree)), sublis(alist, CDR(tree)))); + else + return(tree); +} + +@(defun nsublis (alist tree &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(Cnil, test, test_not, key); + nsublis(alist, &tree); + restoreTEST; + @(return tree) +@) + +/* + Nsublis(alist, treep) stores + the result of substiting *treep by alist + to *treep. +*/ +void +nsublis(cl_object alist, cl_object *treep) +{ + cl_object x = alist; + + cs_check(alist); + loop_for_in(x) { + item_compared = car(CAR(x)); + if (TEST(*treep)) { + *treep = CDAR(x); + return; + } + } end_loop_for_in; + if (CONSP(*treep)) { + nsublis(alist, &CAR(*treep)); + nsublis(alist, &CDR(*treep)); + } +} + +@(defun member (item list &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(item, test, test_not, key); + loop_for_in(list) { + if (TEST(CAR(list))) + goto L; + } end_loop_for_in; + restoreTEST; + @(return list) +@) + +bool +member_eq(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (x == CAR(l)) + return(TRUE); + } end_loop_for_in; + return(FALSE); +} + +@(defun si::memq (x l) +@ + loop_for_in(l) { + if (x == CAR(l)) + @(return l) + } end_loop_for_in; + @(return Cnil) +@) + +/* Added for use by the compiler, instead of open coding them. Beppe */ +cl_object +memq(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (x == CAR(l)) + return(l); + } end_loop_for_in; + return(Cnil); +} + +cl_object +memql(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (eql(x, CAR(l))) + return(l); + } end_loop_for_in; + return(Cnil); +} + +cl_object +member(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (equal(x, CAR(l))) + return(l); + } end_loop_for_in; + return(Cnil); +} +/* End of addition. Beppe */ + +PREDICATE2(Lmember) + +@(defun member1 (item list &key test test_not key) + saveTEST; +@ + protectTEST; + if (key != Cnil) + item = _funcall(2, key, item); + setupTEST(item, test, test_not, key); + loop_for_in(list) { + if (TEST(CAR(list))) + goto L; + } end_loop_for_in; + restoreTEST; + @(return list) +@) + +@(defun tailp (y x) +@ + loop_for_on(x) { + if (x == y) + @(return Ct) + } end_loop_for_on; + @(return ((x == y)? Ct : Cnil)) +@) + +cl_return +Ladjoin(int narg, cl_object item, cl_object list, cl_object k1, cl_object v1, + cl_object k2, cl_object v2, cl_object k3, cl_object v3) +{ + cl_object output; + + if (narg < 2) + FEtoo_few_arguments(&narg); + output = Lmember1(narg, item, list, k1, v1, k2, v2, k3, v3); + if (Null(output)) + output = CONS(item, list); + else + output = list; + return1(output); +} + +@(defun acons (x y z) +@ + @(return CONS(CONS(x, y), z)) +@) + +@(defun pairlis (keys data &optional a_list) + cl_object k, d; +@ + k = keys; + d = data; + loop_for_in(k) { + if (ENDP(d)) + goto error; + a_list = CONS(CONS(CAR(k), CAR(d)), a_list); + d = CDR(d); + } end_loop_for_in; + if (!ENDP(d)) +error: FEerror("The keys ~S and the data ~S are not of the same length", + 2, keys, data); + @(return a_list) +@) + + +@(defun assoc_or_rassoc(cl_object (*car_or_cdr)()) + (item a_list &key test test_not key) + saveTEST; +@ + protectTEST; + setupTEST(item, test, test_not, key); + loop_for_in(a_list) { + cl_object pair = CAR(a_list); + if (Null(pair)) + ; + else if (ATOM(pair)) + FEtype_error_alist(pair); + else if (TEST((*car_or_cdr)(CAR(a_list)))) { + a_list = CAR(a_list); + goto L; + } + } end_loop_for_in; + restoreTEST; + @(return a_list) +@) + +cl_return +Lrassoc(int narg, cl_object item, cl_object alist, cl_object k1, cl_object v1, + cl_object k2, cl_object v2) + { return Lassoc_or_rassoc(narg, cdr, item, alist, k1, v1, k2, v2); } +cl_return +Lassoc(int narg, cl_object item, cl_object alist, cl_object k1, cl_object v1, + cl_object k2, cl_object v2) + { return Lassoc_or_rassoc(narg, car, item, alist, k1, v1, k2, v2); } + +/* Added for use by the compiler, instead of open coding them. Beppe */ +cl_object +assq(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (x == CAAR(l)) + return(CAR(l)); + } end_loop_for_in; + return(Cnil); +} + +cl_object +assql(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (eql(x, CAAR(l))) + return(CAR(l)); + } end_loop_for_in; + return(Cnil); +} + +cl_object +assoc(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (equal(x, CAAR(l))) + return(CAR(l)); + } end_loop_for_in; + return(Cnil); +} + +cl_object +assqlp(cl_object x, cl_object l) +{ + loop_for_in(l) { + if (equalp(x, CAR(CAR(l)))) + return(CAR(l)); + } end_loop_for_in; + return(Cnil); +} +/* End of addition. Beppe */ + +PREDICATE2(Lassoc) +PREDICATE2(Lrassoc) diff --git a/src/c/load.d b/src/c/load.d new file mode 100644 index 000000000..2b652842c --- /dev/null +++ b/src/c/load.d @@ -0,0 +1,257 @@ +/* + load.d -- Binary loader (contains also open_fasl_data). +*/ +/* + Copyright (c) 1990, Giuseppe Attardi and William F. Schelter. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +#ifdef __mips +#include +#endif __mips + +/******************************* ------- ******************************/ + +cl_object Kverbose; +cl_object Vload_verbose; +cl_object Vload_print; +cl_object siVload_hooks; +#ifdef PDE +cl_object siVsource_pathname; +#endif PDE +#ifdef RSYM +cl_object siVsymbol_table; +#endif + +@(defun si::load_binary (filename verbose print) + cl_object block; +@ + block = alloc_object(t_codeblock); + block->cblock.name = filename; + dld(filename->string.self, &block->cblock.start, &block->cblock.size); + + if (!Null(verbose)) { + write_str(";;; Address = "); + PRINTescape = FALSE; + write_addr(block->cblock.start); + write_str("\n"); + } + /* call the init_code function */ +#ifdef __mips + cacheflush(block->cblock.start, block->cblock.size, BCACHE); +#endif __mips +#ifdef __NeXT__ + asm("trap #2"); /* MC68040-specific */ +#endif __NeXT__ + read_VV(block, block->cblock.start); + @(return Ct) +@) + +@(defun si::load_source (filename verbose print) + cl_object x, strm; + cl_object (*old_read_ch_fun)() = read_ch_fun; +@ + strm = open_stream(filename, smm_input, Cnil, Cnil); + if (Null(strm)) + @(return Cnil) + if (frs_push(FRS_PROTECT, Cnil)) { + close_stream(strm, TRUE); + frs_pop(); + unwind(nlj_fr, nlj_tag); + } + bds_bind(Vstandard_input, strm); + for (;;) { + preserving_whitespace_flag = FALSE; + detect_eos_flag = TRUE; + read_ch_fun = readc; /* setup for read. Beppe */ + x = read_object_non_recursive(strm); + read_ch_fun = old_read_ch_fun; + if (x == OBJNULL) + break; + { + cl_object lex_old = lex_env; + cl_object bytecodes = Cnil; + + lex_new(); + eval(x, &bytecodes); + lex_env = lex_old; + } + if (print != Cnil) { + setupPRINT(x, symbol_value(Vstandard_output)); + write_object(x, 0); + write_str("\n"); + cleanupPRINT(); + flush_stream(PRINTstream); + } + } + close_stream(strm, TRUE); + frs_pop(); +@) + +@(defun load (pathname + &key (verbose symbol_value(Vload_verbose)) + (print symbol_value(Vload_print)) + (if_does_not_exist Kerror) + &aux pntype hooks filename function defaults) + bds_ptr old_bds_top; +@ + pathname = coerce_to_physical_pathname(pathname); + defaults = symbol_value(Vdefault_pathname_defaults); + defaults = coerce_to_physical_pathname(defaults); + pathname = merge_pathnames(pathname, defaults, Knewest); + pntype = pathname->pathname.type; + + filename = Cnil; + hooks = symbol_value(siVload_hooks); + if (!Null(pntype) && (pntype != Kwild)) { + /* If filename already has an extension, make sure + that the file exists */ + filename = coerce_to_filename(pathname); + if (!file_exists(filename)) + FEcannot_open(filename); + function = cdr(assoc(pathname->pathname.type, hooks)); + } else loop_for_in(hooks) { + /* Otherwise try with known extensions until a matching + file is found */ + pathname->pathname.type = CAAR(hooks); + filename = coerce_to_filename(pathname); + function = CDAR(hooks); + if (file_exists(filename)) + break; + else + filename = Cnil; + } end_loop_for_in; + if (Null(filename)) { + if (Null(if_does_not_exist)) + @(return Cnil) + else + FEcannot_open(pathname); + } + + if (verbose != Cnil) { + setupPRINT(filename, symbol_value(Vstandard_output)); + if (file_column(PRINTstream) != 0) + write_str("\n"); + write_str(";;; Loading "); + PRINTescape = FALSE; + write_object(filename, 0); + write_str("\n"); + cleanupPRINT(); + flush_stream(PRINTstream); + } + old_bds_top = bds_top; + bds_bind(Vpackage, symbol_value(Vpackage)); +#ifdef PDE + bds_bind(siVsource_pathname, filename); +#endif PDE + if (frs_push(FRS_PROTECT, Cnil)) { + frs_pop(); + bds_unwind(old_bds_top); /* Beppe says this is necessary */ + unwind(nlj_fr, nlj_tag); + } + if (Null(function)) + siLload_source(3, filename, verbose, print); + else + funcall(4, function, filename, verbose, print); + frs_pop(); + bds_unwind(old_bds_top); + if (print != Cnil) { + setupPRINT(filename, symbol_value(Vstandard_output)); + if (file_column(PRINTstream) != 0) + write_str("\n"); + write_str(";;; Finished loading "); + PRINTescape = FALSE; + write_object(filename, 0); + write_str("\n"); + cleanupPRINT(); + flush_stream(PRINTstream); + } + @(return pathname) +@) + + +/* ---------------------------------------------------------------------- + * Binary file loader utilities + * ---------------------------------------------------------------------- + */ +#ifdef RSYM +static int symbol_table_built = 0; +extern int read_special_symbols(const char *); +void +build_symbol_table() +{ + cl_object file; + const char *tmpfile; + file = namestring(Lmerge_pathnames(2, SYM_VAL(siVsymbol_table), + SYM_VAL(siVsystem_directory))); + tmpfile = file->string.self; + if (!symbol_table_built) + if (read_special_symbols(tmpfile) < 0) + FEerror("Could not read symbol table from ~A", 1, make_string_copy(tmpfile)); +} +#endif + +const char * +system_directory() +{ + cl_object dir = SYM_VAL(siVsystem_directory); + while (type_of(dir) != t_string) + FEerror("The value of sys::*system-directory* is not a string, ~A", 1, dir); + return dir->string.self; +} + +/* ---------------------------------------------------------------------- */ +#if 0 + +@(defun si::faslink (file lib) + bds_ptr old_bds_top; + cl_object package; +@ + check_type_string(&lib); + /* INV: coerce_to_physical_pathname() checks types */ + file = coerce_to_filename(file); + file->pathname.type = FASL_string; + file = namestring(file); + package = symbol_value(Vpackage); + old_bds_top = bds_top; + bds_bind(Vpackage, package); + faslink(file, lib); + bds_unwind(old_bds_top); + @(return Cnil) +@) +#endif unix + +void +init_load(void) +{ + cl_object load_source, load_binary; + + SYM_VAL(Vload_verbose) = Ct; + SYM_VAL(Vload_print) = Cnil; +#ifdef PDE + SYM_VAL(siVsource_pathname) = Cnil; +#endif PDE + + load_source = make_si_ordinary("LOAD-SOURCE"); + load_binary = make_si_ordinary("LOAD-BINARY"); + SYM_VAL(siVload_hooks) = list(4, + CONS(make_simple_string("o"), load_binary), + CONS(make_simple_string("lsp"), load_source), + CONS(make_simple_string("lisp"), load_source), + CONS(Cnil, load_source)); + +#ifdef RSYM + SYM_VAL(siVsymbol_table) = make_simple_string("ecl.sym"); +#endif +} diff --git a/src/c/lwp.d b/src/c/lwp.d new file mode 100644 index 000000000..1909f1b73 --- /dev/null +++ b/src/c/lwp.d @@ -0,0 +1,871 @@ +/* + lwp.d -- Light weight processes. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +lpd main_lpd; +lpd *clwp = &main_lpd; +int critical_level = 0; +pd *running_head; /* front of running pd's */ +pd *running_tail; /* back of running pd's */ +pd main_pd; + +/******************************* IMPORTS ******************************/ + +extern scheduler_interruption; /* in unixint.c */ +extern int writec_PRINTstream(); +extern cl_object readc(); +extern gc(); +extern enum type garbage_parameter; + +/******************************* ------- ******************************/ + +#define thread_switch() { setTimer(0); enable_scheduler(); \ + scheduler(0, 0, NULL); } + +static bool timer_active = FALSE; +static bool scheduler_disabled = FALSE; +static int scheduler_level = 0; /* tito */ +static bool reset_timer = FALSE; +static int running_processes = 1; +static int absolute_time = 0; + +cl_object Srunning; +cl_object Ssuspended; +cl_object Swaiting; +cl_object Sstopped; +cl_object Sdead; +cl_object siSthread_top_level; + +static cl_object main_thread; + +static +setTimer(long time) +{ + struct itimerval oldtimer; + struct itimerval itimer; + itimer.it_value.tv_sec = 0; + itimer.it_value.tv_usec = time; + itimer.it_interval.tv_sec = 0; + itimer.it_interval.tv_usec = 0; + setitimer(ITIMER_REAL, &itimer, &oldtimer); +} + +pd * +dequeue() +{ + pd *tmp; + tmp = running_head; + if (running_head != NULL) + running_head = running_head->pd_next; + return tmp; +} + +pd * +make_pd() +{ + pd *new_pd; lpd *npd; + int i; + + /* Allocate a new descriptor for the new lwp */ + new_pd = (pd *)malloc(sizeof(pd)); + + /* create a new stack ... */ + new_pd->pd_base = (int *)malloc(STACK_SIZE * sizeof(int)); + new_pd->pd_status = SUSPENDED; + + /* allocate a lisp descriptor: + * using the calloc here it's possible to avoid the + * critical section in the various push operations + */ + npd = new_pd->pd_lpd = (lpd *)calloc(sizeof(lpd), 1); + + /* initialize it */ + + /* bind stack */ + npd->lwp_bdssize = BDSSIZE + 2*BDSGETA; + npd->lwp_bdsorg = malloc(npd->lwp_bdssize * sizeof(*npd->lwp_bdsorg)); + npd->lwp_bdstop = npd->lwp_bdsorg-1; + npd->lwp_bdslimit = &npd->lwp_bdsorg[npd->lwp_bdssize - 2*BDSGETA]; + + /* C stack */ + /* cssize is different now for the main thread only, but you might + want to create threads with different stack sizes */ + +#ifdef DOWN_STACK + npd->lwp_cs_org = new_pd->pd_base + STACK_SIZE - 1; + npd->lwp_cs_limit = new_pd->pd_base - 1; +#else + npd->lwp_cs_org = new_pd->pd_base; + npd->lwp_cs_limit = npd->lwp_cs_org + STACK_SIZE; +#endif + /* invocation history stack */ + npd->lwp_ihssize = IHSSIZE + 2*IHSGETA; + npd->lwp_ihsorg = malloc(npd->lwp_ihssize * sizeof(*npd->lwp_ihsorg)); + npd->lwp_ihstop = npd->lwp_ihsorg-1; + npd->lwp_ihslimit = &npd->lwp_ihsorg[npd->lwp_ihssize - 2*IHSGETA]; + /* frame stack */ + npd->lwp_frs_size = FRSSIZE + 2*FRSGETA; + npd->lwp_frs_org = malloc(npd->lwp_frs_size * sizeof(*npd->lwp_frs_org)); + npd->lwp_frs_top = npd->lwp_frs_org-1; + npd->lwp_frs_limit = &npd->lwp_frs_org[npd->lwp_frs_size - 2*FRSGETA]; + + npd->lwp_alloc_temporary = OBJNULL; + npd->lwp_backq_level = 0; + npd->lwp_eval1 = 0; + /* for gc */ + npd->lwp_fmt_temporary_stream = OBJNULL; + npd->lwp_fmt_temporary_string = OBJNULL; + + npd->lwp_PRINTstream = Cnil; + npd->lwp_PRINTescape = TRUE; + npd->lwp_PRINTpretty = FALSE; + npd->lwp_PRINTcircle = FALSE; + npd->lwp_PRINTbase = 10; + npd->lwp_PRINTradix = FALSE; + npd->lwp_PRINTcase = Kdowncase; + npd->lwp_PRINTgensym = TRUE; + npd->lwp_PRINTlevel = -1; + npd->lwp_PRINTlength = -1; + npd->lwp_PRINTarray = FALSE; + npd->lwp_write_ch_fun = writec_PRINTstream; + npd->lwp_output_ch_fun = writec_PRINTstream; + npd->lwp_read_ch_fun = readc; + + npd->lwp_READtable = symbol_value(Vreadtable); + npd->lwp_READdefault_float_format = 'S'; + npd->lwp_READbase = 10; + npd->lwp_READsuppress = FALSE; + npd->lwp_delimiting_char = OBJNULL; + npd->lwp_detect_eos_flag = FALSE; + npd->lwp_in_list_flag = FALSE; + npd->lwp_dot_flag = FALSE; + npd->lwp_sharp_eq_context_max = 0; + + /* for gc */ + npd->lwp_gensym_prefix = OBJNULL; + npd->lwp_gentemp_prefix = OBJNULL; + npd->lwp_token = OBJNULL; + + /* lex_env copy */ + npd->lwp_lex_env = npd->lwp_lex; + + /* ihs_push(Cnil) */ + (++npd->lwp_ihs_top)->ihs_function = Cnil; + npd->lwp_ihs_top->ihs_base = npd->lwp_lex_env; + + /* Now the allocation. If the gc is invoked we are able to mark + * the objects already allocated + */ + npd->lwp_fmt_temporary_stream = make_string_output_stream(64); + npd->lwp_fmt_temporary_string = + npd->lwp_fmt_temporary_stream->stream.object0; + + npd->lwp_gentemp_prefix = make_simple_string("T"); + npd->lwp_token = alloc_simple_string(LISP_PAGESIZE); + npd->lwp_token->string.self = alloc_atomic(LISP_PAGESIZE); + npd->lwp_token->string.fillp = 0; + npd->lwp_token->string.hasfillp = TRUE; + npd->lwp_token->string.adjustable = TRUE; + + for (i=0; i<3; i++) + npd->lwp_bignum_register[i] = alloc_object(t_bignum); + + return new_pd; +} + +update_queue() +{ + register pd *dead_pd; + pd *last = running_tail; + + do + switch (running_head->pd_status) { + + case DEAD: + + /* remove the dead process */ + dead_pd = dequeue(); + /* free the lisp descriptor */ + free(dead_pd->pd_lpd); + /* free the memory allocated for the stack and the descriptor */ + free(dead_pd->pd_base); + free(dead_pd); + break; + +/* case SUSPENDED: */ + case DELAYED: + + if (running_head->pd_slice != 0) + if (absolute_time > running_head->pd_slice) { + + /* the time slice has expired */ + running_head->pd_slice = 0; + + if ((running_head->pd_thread->thread.cont) != OBJNULL) { + /* in this case a continuation was created before %delay */ + running_head->pd_thread->thread.cont->cn.cn_timed_out = TRUE; + running_head->pd_thread->thread.cont = OBJNULL; + } + running_head->pd_status = RUNNING; + return; /* now you are a running process */ + } + ROTQUEUE(); + break; + + case WAITING: /* waiting processes need to be scheduled */ + case RUNNING: + return; /* found schedulable process */ + + default: /* currently is only STOPPED */ + ROTQUEUE(); + break; + } + while (running_head != last); +} + +activate_thread(cl_object thread) +{ + pd *npd = thread->thread.data; + + /* jump on the new C stack */ + if (sigsetjmp(npd->pd_env, 1) == 0) { +#define STACK_MARGIN 160 /* longjmp writes also under the sp level */ +#ifdef DOWN_STACK +# ifdef __linux + npd->pd_env[0].__jmpbuf[0].__sp = + stack_align((int)(npd->pd_base) + sizeof(int)*STACK_SIZE - STACK_MARGIN); + npd->pd_lpd->lwp_cssize = + npd->pd_env[0].__jmpbuf[0].__sp - (int)npd->pd_base; +# else + npd->pd_env[JB_SP] = + stack_align((int)(npd->pd_base) + sizeof(int)*STACK_SIZE - STACK_MARGIN); + npd->pd_lpd->lwp_cssize = + npd->pd_env[JB_SP] - (int)npd->pd_base; +# endif +#else + npd->pd_env[JB_SP] = + stack_align((int)(npd->pd_base)); + npd->pd_lpd->lwp_cssize = sizeof(int) * STACK_SIZE - STACK_MARGIN; +#endif DOWN_STACK +#ifdef JB_FP + npd->pd_env[JB_FP] = npd->pd_env[JB_SP]; +#endif + return; + } + + /* Back here when thread is first resumed. + * + * WARNING: args and locals are no more accessible from here on, + * since we reenter with longjmp onto a new stack. + */ + +#ifndef sun4sol2 + /* on SunOS sigmask is 0x82001 here */ + sigsetmask(sigblock(0) & ~(sigmask(SIGALRM))); +#endif + + { int i; + for (i = clwp->lwp_nValues; i > 0;) + VALUES(i) = VALUES(--i); + VALUES(0) = clwp->lwp_thread->thread.entry; + apply(clwp->lwp_nValues+1, siSthread_top_level, &VALUES(0)); + } + /* Termination */ + + terpri(Cnil); + running_head->pd_status = DEAD; + running_head->pd_thread->thread.data = NULL; + running_processes--; + + update_queue(); + thread_next(); /* update_queue has freed our stack!!! */ +} + +/* + * switch to the first thread on queue + */ +thread_next() +{ + /* unwind the bind stack */ + lwp_bds_unwind(clwp->lwp_bind_stack, clwp->lwp_bds_top); + + /* switch clwp */ + clwp = running_head->pd_lpd; + + /* restore Values pointer */ + Values = clwp->lwp_Values; + + /* wind the bind stack */ + lwp_bds_wind(clwp->lwp_bind_stack, clwp->lwp_bds_top); + + /* reset the timer */ + if (running_processes > 1) { + timer_active = TRUE; + setTimer(REALQUANTUM); + } else { + timer_active = FALSE; + absolute_time = 0; + } + siglongjmp(running_head->pd_env, 1); +} + +/* + * Called when time slice expires or explicitily to switch thread + */ +scheduler(int sig, int code, struct sigcontext *scp) +{ + int val; + +#if defined(SYSV) || defined(__svr4__) || defined(__linux) + signal(SIGALRM, scheduler); +#endif SYSV + + absolute_time++; + if (critical_level > 0) { /* within critical section */ + scheduler_interrupted = TRUE; + scheduler_interruption = SCHEDULER_INT; + return; + } + if (scheduler_level > 0) { /* abilitation check */ + scheduler_interrupted = TRUE; + return; + } + + val = sigsetjmp(running_head->pd_env, 1); + + if (val == 1) /* resume interrupted thread execution */ + return; /* coming back from longjmp in thread_next */ + + if (val == 2) /* coming back from longjmp in GC */ + gc(garbage_parameter); /* GC will return to the previous thread */ + + ROTQUEUE(); + thread_next(); +} + +/* + * Handle signal received within critical section + */ +interruption_handler() +{ + scheduler_interrupted = FALSE; + + switch (scheduler_interruption) { + + case SCHEDULER_INT: + thread_switch(); + break; + + case ERROR_INT: + sigint(); + break; + } +} + +lwp_bds_wind(bds_ptr base, bds_ptr top) +{ + cl_object temp; + + for (; top >= base; base++) { + temp = SYM_VAL(base->bds_sym); + SYM_VAL(base->bds_sym) = base->bds_val; + base->bds_val = temp; + } +} + +lwp_bds_unwind(bds_ptr base, bds_ptr top) +{ + cl_object temp; + + for (; top >= base; top--) { + temp = SYM_VAL(top->bds_sym); + SYM_VAL(top->bds_sym) = top->bds_val; + top->bds_val = temp; + } +} + +resume(pd *rpd) +{ + register pd *p; + + start_critical_section(); + running_processes++; + + rpd->pd_status = RUNNING; + for (p = running_head; (p != rpd) && (p != NULL); p = p->pd_next) ; + if (p == NULL) + ENQUEUE(rpd); + end_critical_section(); + + if (!timer_active) { + timer_active = TRUE; + setTimer(REALQUANTUM); + } +} + +/*********** + * + * THREADS + * + ***********/ + + +@(defun si::thread_break_in () +@ + alarm(0); + @(return Cnil) +@) + +@(defun si::thread_break_quit () + /* reset everything in MT */ + pd *p; +@ + /* this is done in any case to remedy the problem with C-c handling */ + signal(SIGALRM, scheduler); + + if (timer_active) { + /* reset the critical and disable-scheduler environment */ + scheduler_disabled = FALSE; + scheduler_level = 0; + critical_level = 0; + scheduler_interrupted = 0; + + for (p = running_head; (p != NULL); p = p->pd_next) + if (p != &main_pd) + p->pd_status = DEAD; + else { + p->pd_status = RUNNING; + p->pd_thread->thread.cont = OBJNULL; + } + + if (running_head != &main_pd) { + update_queue(); + thread_next(); + /* here one should deallocate the main-thread function */ + } + else + thread_switch(); + } + @(return Cnil) +@) + +@(defun si::thread_break_resume () +@ + /* Restart the timer that might have been + * changed by the interrupt handling + */ + signal(SIGALRM, scheduler); + if (timer_active) + thread_switch(); + @(return Cnil) +@) + +@(defun thread_list () + pd *p; + cl_object tmp, x = CONS(running_head->pd_thread, Cnil); +@ + tmp = x; + start_critical_section(); + + for (p = running_head->pd_next; (p != NULL); p = p->pd_next) { + CDR(tmp) = CONS(p->pd_thread, Cnil); + tmp = CDR(tmp); + } + + end_critical_section(); + + @(return x) +@) + +@(defun make_thread (fun) + cl_object x; + pd *npd; +@ + /* Just one argument for the time being */ + + if (SYMBOLP(fun)) { + if (fun->symbol.isform || fun->symbol.mflag) + FEinvalid_function(fun); + if (SYM_FUN(fun) == OBJNULL) + FEundefined_function(fun); + /* fun = SYM_FUN(fun); confusing */ + } + + x = alloc_object(t_thread); + x->thread.entry = fun; + x->thread.size = sizeof(pd); + x->thread.data = npd = make_pd(); + x->thread.cont = OBJNULL; + + npd->pd_thread = x; + npd->pd_slice = 0; + + /* Backpointer to thread */ + npd->pd_lpd->lwp_thread = x; + + activate_thread(x); + + @(return x) +@) + +@(defun deactivate (thread) +@ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + + if (thread->thread.data == NULL || + thread->thread.data->pd_status != RUNNING) + FEerror("Cannot deactivate a thread not running", 0); + + start_critical_section(); /* tito */ + thread->thread.data->pd_status = STOPPED; + running_processes--; + if (thread->thread.data == running_head) { + critical_level--; /* end_critical_section() */ + update_queue(); + thread_next(); + } else + end_critical_section(); + @(return Cnil) +@) + +@(defun reactivate (thread) +@ + start_critical_section(); + + if (type_of(thread) != t_thread) { + FEwrong_type_argument(Sthread, thread); + } + + if (thread->thread.data == NULL || + thread->thread.data->pd_status != STOPPED) + FEerror("Cannot reactivate a thread not stopped", 0); + + start_critical_section(); /* tito */ + thread->thread.data->pd_status = RUNNING; + running_processes++; + + if (!timer_active) { + timer_active = TRUE; + setTimer(REALQUANTUM); + } + + end_critical_section(); + @(return Cnil) +@) + +@(defun kill_thread (thread) +@ + /* The following code is not enough. + Consider: The scheduler can be disabled + What about killing the current thread? + */ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + + if (thread->thread.data != NULL) { + start_critical_section(); + thread->thread.data->pd_status = DEAD; + if (thread->thread.data->pd_lpd == clwp) { + /* if a thread kills itself the scheduler is to be called */ + thread->thread.data = NULL; + critical_level--; /* end_critical_section() */ + update_queue(); + thread_next(); + } + else { + thread->thread.data = NULL; + end_critical_section(); + } + } + @(return) +@) + +@(defun current_thread () +@ + @(return clwp->lwp_thread) +@) + +@(defun thread_status (thread) + cl_object output; +@ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + + if (thread->thread.data != NULL) + switch (thread->thread.data->pd_status) { + case RUNNING: + output = Srunning; + break; + case SUSPENDED: + output = Ssuspended; + break; + case WAITING: + output = Swaiting; + break; + case STOPPED: + output = Sstopped; + break; + case DEAD: + output = Sdead; + break; + default: + FEerror("Unexpected type for thread ~A", 1, thread); + } + else + output = Sdead; + @(return output) +@) + + +/*************** + * + * CONTINUATIONS + * + ***************/ + +@(defun make_continuation (thread) + cl_object x; +@ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + + if (thread->thread.cont) + FEerror("A continuation for thread ~A already exists.", 1, thread); + + if (thread->thread.data == NULL || + thread->thread.data->pd_status == DEAD) { + FEerror("Thread ~A is DEAD.", 1, thread); + } + + x = alloc_object(t_cont); + + x->cn.cn_thread = thread; + x->cn.cn_resumed = FALSE; + x->cn.cn_timed_out = FALSE; + + thread->thread.cont = x; + @(return x) +@) + +/* Returns the thread associated to a continuation */ +@(defun thread_of (cont) +@ + if (type_of(cont) != t_cont) + FEwrong_type_argument(Scont, cont); + @(return cont->cn.cn_thread) +@) + +/* Returns the continuation associated to a thread, if it exists */ +@(defun continuation_of (thread) +@ + if (type_of(thread) != t_thread) + FEwrong_type_argument(Sthread, thread); + @(return (thread->thread.cont? thread->thread.cont : Cnil)) +@) + +@(defun resume (cont &rest args) + int i; + cl_object *thread_Values; +@ + if (Null(cont)) + @(return Cnil) + + if (type_of(cont) != t_cont) + FEwrong_type_argument(Scont, cont); + + if (cont->cn.cn_resumed) + FEerror("The continuation has already been resumed.", 0); + + if (cont->cn.cn_timed_out) + FEerror("The continuation has been timed out.", 0); + + if (cont->cn.cn_thread->thread.data == NULL) + FEerror("The continuation cannot be resumed. Its thread is DEAD.", 0); + + if (cont->cn.cn_thread->thread.data->pd_status != SUSPENDED && + cont->cn.cn_thread->thread.data->pd_status != DELAYED) + FEerror("The continuation cannot be resumed. Its thread isn't suspended", 0); + + /* Push the arguments on the value stack of thread */ + + thread_Values = cont->cn.cn_thread->thread.data->pd_lpd->lwp_Values; + + for (i = 1; i < narg; i++) + *(thread_Values++) = va_arg(args, cl_object); + cont->cn.cn_thread->thread.data->pd_lpd->lwp_nValues = narg-1; + + cont->cn.cn_resumed = TRUE; + cont->cn.cn_thread->thread.cont = OBJNULL; + + /* If you are waiting on a slice expiring I reset your slice */ + cont->cn.cn_thread->thread.data->pd_slice = 0; + + resume(cont->cn.cn_thread->thread.data); + + @(return cont->cn.cn_thread) +@) + + +/*************** + * + * SCHEDULING + * + ***************/ + +@(defun disable_scheduler () +@ + scheduler_level++; + @(return Cnil) +@) + +@(defun enable_scheduler () +@ + enable_scheduler(); + @(return Cnil) +@) + +enable_scheduler() +{ + scheduler_level = 0; + + if (scheduler_interrupted) { + scheduler_interrupted = FALSE; + thread_switch(); + } +} + +@(defun suspend () +@ + if (timer_active) { + running_head->pd_status = SUSPENDED; + running_processes--; + thread_switch(); + /* When resumed it will be provided with the Values to return */ +#error "This is very very wrong!" + RETURN(running_head->pd_lpd->lwp_nValues); + } + else + FEerror("No other active thread.", 0); +@) + +@(defun delay (interval) + int z; +@ + z = fixnnint(interval); + + if (timer_active) { + running_head->pd_status = DELAYED; + running_processes--; + + /* Translate seconds in number of scheduler slices */ + running_head->pd_slice = z * 10 + absolute_time; + + thread_switch(); + + /* When resumed it will be provided with the Values to return */ +#error "This is very very wrong!" + RETURN(running_head->pd_lpd->lwp_nValues); + } + else + sleep(z); +@) + +@(defun thread_wait (fun &rest args) +@ + start_critical_section(); + running_head->pd_status = WAITING; + running_processes--; + end_critical_section(); + + for (;;) { + if (_apply(narg-1, fun, args) != Cnil) + break; + else if (timer_active) { + /* the time slice has not been used */ + absolute_time--; + thread_switch(); + } else + FEerror("The condition will never be satisfied for lack of active processes", 0); + } + running_head->pd_status = RUNNING; + running_processes++; + end_critical_section(); + returnn(); +@) + +@(defun thread_wait_with_timeout (timeout fun &rest args) +@ + /* We have to translate seconds in scheduler call number */ + start_critical_section(); + running_head->pd_slice = fixnnint(timeout) * 10 + absolute_time; + + running_head->pd_status = WAITING; + running_processes--; + end_critical_section(); + + for (;;) { + + if (absolute_time > running_head->pd_slice) { + /* the time slice has expired */ + VALUES(0) = Cnil; + NValues = 1; + break; + } + + if (_apply(narg-1, fun, args) != Cnil) + break; + else { + /* the time slice has not been used */ + absolute_time--; + thread_switch(); + } + } + + start_critical_section(); + running_head->pd_slice = 0; + running_head->pd_status = RUNNING; + running_processes++; + end_critical_section(); + returnn(); +@) + +enable_lwp() +{ + signal(SIGALRM, scheduler); +} + +init_lwp() +{ pd *temp_pd; + + temp_pd = &main_pd; + PUSH(temp_pd); + + main_thread = alloc_object(t_thread); + main_pd.pd_thread = main_thread; + main_thread->thread.entry = Cnil; + main_thread->thread.size = sizeof (pd); + main_thread->thread.data = &main_pd; + main_thread->thread.cont = OBJNULL; + /* Backpointer to thread */ + main_pd.pd_status = RUNNING; + main_pd.pd_lpd = &main_lpd; + main_lpd.lwp_thread = main_thread; + register_root(&main_thread); +} diff --git a/src/c/macros.d b/src/c/macros.d new file mode 100644 index 000000000..cb2c07ad0 --- /dev/null +++ b/src/c/macros.d @@ -0,0 +1,137 @@ +/* + macros.c -- Macros. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* REQUIRES ******************************/ + +/* Requires expand-defmacro, from lsp/defmacro.lsp */ + +/******************************* EXPORTS ******************************/ + +cl_object Vmacroexpand_hook; +cl_object siSexpand_defmacro; +cl_object siVinhibit_macro_special; + +/******************************* ------- ******************************/ + +/* + MACRO_DEF is an internal function which, given a form, returns + the expansion function if the form is a macro form. Otherwise, + MACRO_DEF returns NIL. +*/ +cl_object +search_symbol_macro(cl_object name, cl_object env) +{ + cl_object record = assq(name, CAR(env)); + if (CONSP(record) && CADR(record) == siSsymbol_macro) + return CADDR(record); + return Cnil; +} + +cl_object +search_macro(cl_object name, cl_object env) +{ + return lex_sch(CDR(env), name, Smacro); +} + +cl_object +macro_def(cl_object form, cl_object env) +{ + cl_object head, fd; + + if (ATOM(form)) { + if (!SYMBOLP(form)) + return Cnil; + /* First look for SYMBOL-MACROLET definitions */ + fd = search_symbol_macro(form, env); + return fd; + } + head = CAR(form); + if (!SYMBOLP(head)) + return(Cnil); + fd = search_macro(head, env); + if (!Null(fd)) + return fd; + else if (head->symbol.mflag) + return(SYM_FUN(head)); + else + return(Cnil); +} + +@(defun macroexpand (form &optional (env Cnil)) + cl_object new_form = OBJNULL; + cl_object done = Cnil; +@ + new_form = macro_expand1(form, env); + while (new_form != form) { + done = Ct; + form = new_form; + new_form = macro_expand(form, env); + } + @(return new_form done) +@) + +@(defun macroexpand_1 (form &optional (env Cnil)) + cl_object new_form; +@ + new_form = macro_expand1(form, env); + @(return new_form (new_form == form? Cnil : Ct)) +@) + +/* + MACRO_EXPAND1 is an internal function which simply applies the + function EXP_FUN to FORM. On return, the expanded form is stored + in VALUES(0). +*/ +cl_object +macro_expand1(cl_object form, cl_object env) +{ + cl_object hook, lex; + cl_object exp_fun; + + exp_fun = macro_def(form, env); + if (Null(exp_fun)) + return form; + hook = symbol_value(Vmacroexpand_hook); + if (hook == Sfuncall) + return funcall(3, exp_fun, form, env); + else + return funcall(4, hook, exp_fun, form, env); +} + +/* + MACRO_EXPAND expands a form as many times as possible and returns + the finally expanded form. +*/ +cl_object +macro_expand(cl_object form, cl_object env) +{ + cl_object new_form; + + for (new_form = OBJNULL; new_form != form; form = new_form) { + new_form = macro_expand1(form, env); + } + return new_form; +} + +void +init_macros(void) +{ + SYM_VAL(Vmacroexpand_hook) = Sfuncall; + SYM_VAL(siVinhibit_macro_special) = Cnil; +} diff --git a/src/c/main.d b/src/c/main.d new file mode 100644 index 000000000..26b06a882 --- /dev/null +++ b/src/c/main.d @@ -0,0 +1,258 @@ +/* + main.c -- +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +/* ******** WARNING ******** + Do not insert any data definitions before data_start! + Since this is the first file linked, the address of the following + variable should correspond to the start of initialized data space. + On some systems this is a constant that is independent of the text + size for shared executables. On others, it is a function of the + text size. In short, this seems to be the most portable way to + discover the start of initialized data space dynamically at runtime, + for either shared or unshared executables, on either swapping or + virtual systems. It only requires that the linker allocate objects + in the order encountered, a reasonable model for most Unix systems. + Fred Fish, UniSoft Systems Inc. */ + +/* On SGI one could use extern _fdata[] instead */ + +int data_start = (int)&data_start; + +/******************************** IMPORTS *****************************/ + +#include "ecls.h" +#ifdef HAVE_SYS_UTSNAME_H +# include +#endif +#ifdef TK +# include "tk.h" +#endif + +/******************************* EXPORTS ******************************/ + +cl_object Vfeatures; +cl_object siVsystem_directory; +const char *ecl_self; + +/******************************* ------- ******************************/ + +static int ARGC; +static char **ARGV; + +#ifdef THREADS +static cl_object siVthread_top; +#endif THREADS +static cl_object siStop_level; + +#if !defined(GBC_BOEHM) +static char stdin_buf[BUFSIZ]; +static char stdout_buf[BUFSIZ]; +#endif + +int +main(int argc, char **argv) +{ +#if !defined(GBC_BOEHM) + setbuf(stdin, stdin_buf); + setbuf(stdout, stdout_buf); +#endif + + ARGC = argc; + ARGV = argv; + ecl_self = argv[0]; + + init_alloc(); + alloc_stacks(&argc); + +#ifndef MSDOS + ecl_self = expand_pathname(ecl_self); +#endif MSDOS + + /*ihs_push(Cnil, lex);*/ + lex_new(); + + /* Initialize library */ + init_lisp(); + + /* Jump to top level */ + SYM_VAL(Vpackage) = user_package; + enable_interrupt(); + siLcatch_bad_signals(0); +#ifdef THREADS + enable_lwp(); +#endif THREADS +#ifdef TK + if (getenv("DISPLAY")) { + Tk_main(FALSE, /* sync */ + "ECL/Tk", /* name */ + NULL, /* file */ + getenv("DISPLAY"), /* Xdisplay */ + NULL); /* geometry */ + } +#endif + ihs_push(_intern("TOP-LEVEL", system_package), Cnil); + funcall(1, siStop_level); + return(0); +} + +@(defun quit (&optional (code MAKE_FIXNUM(0))) + cl_fixnum i; +@ + if (!FIXNUMP(code)) + FEerror("Illegal exit code: ~S.", 1, code); + i = fix(code); +#ifdef THREADS + if (clwp != &main_lpd) { + VALUES(0) = Cnil; + NValues = 0; + throw(siVthread_top); + /* never reached */ + } +#endif THREADS + printf("Bye.\n"); + exit(i); +@) + +@(defun si::argc () +@ + @(return MAKE_FIXNUM(ARGC)) +@) + +@(defun si::argv (index) + cl_fixnum i; +@ + if (!FIXNUMP(index) || (i = fix(index)) < 0 || i >= ARGC) + FEerror("Illegal argument index: ~S.", 1, index); + @(return make_string_copy(ARGV[i])) +@) + +@(defun si::getenv (var) + char name[256], *value; + cl_index i; +@ + assert_type_string(var); + if (var->string.fillp >= 256) + FEerror("Too long name: ~S.", 1, var); + for (i = 0; i < var->string.fillp; i++) + name[i] = var->string.self[i]; + name[i] = '\0'; + value = getenv(name); + @(return ((value == NULL)? Cnil : make_string_copy(value))) +@) + +@(defun si::address (x) +@ + @(return MAKE_FIXNUM((int)x)) +@) + +#ifdef HAVE_SYS_UTSNAME_H +@(defun machine_instance () + struct utsname uts; +@ + uname(&uts); + @(return make_string_copy(uts.nodename)) +@) + +@(defun machine_version () + struct utsname uts; +@ + uname(&uts); + @(return make_string_copy(uts.machine)) +@) + +@(defun software_type () + struct utsname uts; +@ + uname (&uts); + @(return make_string_copy(uts.sysname)) +@) + +@(defun software_version () + struct utsname uts; +@ + uname (&uts); + @(return make_string_copy(uts.release)) +@) +#endif + +void +init_main(void) +{ + siStop_level=make_si_ordinary("TOP-LEVEL"); + register_root(&siStop_level); + + make_ordinary("LISP-IMPLEMENTATION-VERSION"); + + SYM_VAL(siVsystem_directory) = make_simple_string("./"); + + { cl_object features; + features = + CONS(make_keyword("ECLS"), + CONS(make_keyword("COMMON"), Cnil)); + +#define ADD_FEATURE(name) features = CONS(make_keyword(name),features) + +#if defined(GBC_BOEHM) + ADD_FEATURE("BOEHM-GC"); +#endif + +#ifdef LOCATIVE + ADD_FEATURE("LOCATIVE"); +#endif LOCATIVE + +#ifdef THREADS + ADD_FEATURE("THREADS"); +#endif THREADS + +#ifdef CLOS + ADD_FEATURE("CLOS"); +#endif CLOS + + ADD_FEATURE("ANSI-CL"); + +#ifdef PDE + ADD_FEATURE("PDE"); +#endif PDE + +/* ---------- Operating System ---------- */ +#ifdef unix + ADD_FEATURE("UNIX"); +#endif +#ifdef BSD + ADD_FEATURE("BSD"); +#endif +#ifdef SYSV + ADD_FEATURE("SYSTEM-V"); +#endif +#ifdef MSDOS + ADD_FEATURE("MS-DOS"); +#endif + + ADD_FEATURE(ARCHITECTURE); + ADD_FEATURE(BRAND); + +#ifdef IEEEFLOAT + ADD_FEATURE("IEEE-FLOATING-POINT"); +#endif + + SYM_VAL(Vfeatures) = features; + } +#ifdef THREADS + siVthread_top = make_si_ordinary("THREAD-TOP"); +#endif THREADS + + make_si_constant("+OBJNULL+", OBJNULL); +} diff --git a/src/c/mapfun.d b/src/c/mapfun.d new file mode 100644 index 000000000..f5ab11dcd --- /dev/null +++ b/src/c/mapfun.d @@ -0,0 +1,145 @@ +/* + mapfun.c -- Mapping. +*/ +/* + Copyright (c) 1993, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +@(defun mapcar (fun onelist &rest lists) + cl_object res, *val = &res; + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + res = Cnil; + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return res) + cars[i] = CAR(cdrs[i]); + cdrs[i] = CDR(cdrs[i]); + } + *val = CONS(_apply(narg, fun, cars), Cnil); + val = &CDR(*val); + } +@) + +@(defun maplist (fun onelist &rest lists) + cl_object res, *val = &res; + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + res = Cnil; + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return res) + cars[i] = cdrs[i]; + cdrs[i] = CDR(cdrs[i]); + } + *val = CONS(_apply(narg, fun, cars), Cnil); + val = &CDR(*val); + } +@) + +@(defun mapc (fun onelist &rest lists) + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return onelist) + cars[i] = CAR(cdrs[i]); + cdrs[i] = CDR(cdrs[i]); + } + apply(narg, fun, cars); + } +@) + +@(defun mapl (fun onelist &rest lists) + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return onelist) + cars[i] = cdrs[i]; + cdrs[i] = CDR(cdrs[i]); + } + apply(narg, fun, cars); + } +@) + +@(defun mapcan (fun onelist &rest lists) + cl_object *x, res, *val = &res; + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + res = Cnil; + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return res) + cars[i] = CAR(cdrs[i]); + cdrs[i] = CDR(cdrs[i]); + } + *val = _apply(narg, fun, cars); + while (CONSP(*val)) + val = &CDR(*val); + } +@) + +@(defun mapcon (fun onelist &rest lists) + cl_object res, *val = &res; + cl_object cdrs[narg-1]; + cl_object cars[narg-1]; /* __GNUC__ */ + int i; +@ + cdrs[0] = onelist; + for (--narg, i = 1; i < narg; i++) + cdrs[i] = va_arg(lists, cl_object); + res = Cnil; + while (TRUE) { + for (i = 0; i < narg; i++) { + if (endp(cdrs[i])) + @(return res) + cars[i] = cdrs[i]; + cdrs[i] = CDR(cdrs[i]); + } + *val = _apply(narg, fun, cars); + while (CONSP(*val)) + val = &CDR(*val); + } +@) diff --git a/src/c/multival.d b/src/c/multival.d new file mode 100644 index 000000000..31aa402c9 --- /dev/null +++ b/src/c/multival.d @@ -0,0 +1,46 @@ +/* + multival.c -- Multiple Values. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + + ECoLisp is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +@(defun values (&rest args) + int i; +@ + /* INV: the number of arguments never exceeds VSSIZE */ + NValues = narg; + if (narg == 0) + VALUES(0) = Cnil; + else for (i = 0; i < narg; i++) + VALUES(i) = va_arg(args, cl_object); + returnn(VALUES(0)); +@) + +@(defun values_list (list) +@ + VALUES(0) = Cnil; + for (NValues=0; !endp(list); list=CDR(list)) { + if (NValues == VSSIZE) + FEerror("Too many values in VALUES-LIST",0); + VALUES(NValues++) = CAR(list); + } + returnn(VALUES(0)); +@) + +void +init_multival(void) +{ + make_constant("MULTIPLE-VALUES-LIMIT",MAKE_FIXNUM(32)); +} diff --git a/src/c/new/all_symbols.d b/src/c/new/all_symbols.d new file mode 100644 index 000000000..0f45fe444 --- /dev/null +++ b/src/c/new/all_symbols.d @@ -0,0 +1,308 @@ +#include "ecls.h" +#include "page.h" + +const struct symbol_info all_symbols[] = { +/* assignment.c */ +{&Ssetf, "SETF", CL_ORDINARY}, +{&Spsetf, "PSETF", CL_ORDINARY}, +{&siSsetf_symbol, "SETF-SYMBOL", SI_ORDINARY}, +{&siSclear_compiler_properties, "CLEAR-COMPILER-PROPERTIES", SI_ORDINARY}, +#ifdef PDE +{&siVrecord_source_pathname_p, "*RECORD-SOURCE-PATHNAME-P*", SI_SPECIAL}, +{&siSrecord_source_pathname, "RECORD-SOURCE-PATHNAME", SI_ORDINARY}, +#endif + +/* backq.c */ +{&siScomma, ",", SI_ORDINARY}, +{&siScomma_at, ",@@", SI_ORDINARY}, +{&siScomma_dot, ",.", SI_ORDINARY}, +{&SlistX, "LIST*", CL_ORDINARY}, +{&Sappend, "APPEND", CL_ORDINARY}, +{&Snconc, "NCONC", CL_ORDINARY}, + +/* bind.c */ +{&SAoptional, "&OPTIONAL", CL_ORDINARY}, +{&SArest, "&REST", CL_ORDINARY}, +{&SAkey, "&KEY", CL_ORDINARY}, +{&SAallow_other_keys, "&ALLOW-OTHER-KEYS", CL_ORDINARY}, +{&SAaux, "&AUX", CL_ORDINARY}, + +/* block.c */ +{&Sblock, "BLOCK", CL_ORDINARY}, + +/* clos.c */ +#ifdef CLOS +{&siSXclass_name_hash_tableX, "*CLASS-NAME-HASH-TABLE*", SI_SPECIAL}, +{&Sclass, "CLASS", CL_ORDINARY}, +{&Sbuilt_in, "BUILT-IN", CL_ORDINARY}, +#endif + +/* compiler.c */ +{&siSlambda_block, "LAMBDA-BLOCK", CL_ORDINARY}, + +/* conditional.c */ +{&Sotherwise, "OTHERWISE", CL_ORDINARY}, + +/* error.c */ +{&siSuniversal_error_handler, "UNIVERSAL-ERROR-HANDLER", SI_ORDINARY}, +{&siSterminal_interrupt, "TERMINAL-INTERRUPT", SI_ORDINARY}, + +/* eval.c */ +{&Sapply, "APPLY", CL_ORDINARY}, +{&Sfuncall, "FUNCALL", CL_ORDINARY}, +{&Vevalhook, "*EVALHOOK*", CL_SPECIAL}, +{&Vapplyhook, "*APPLYHOOK*", CL_SPECIAL}, + +/* file.c */ +{&Vstandard_input, "*STANDARD-INPUT*", CL_SPECIAL}, +{&Vstandard_output, "*STANDARD-OUTPUT*", CL_SPECIAL}, +{&Verror_output, "*ERROR-OUTPUT*", CL_SPECIAL}, +{&Vquery_io, "*QUERY-IO*", CL_SPECIAL}, +{&Vdebug_io, "*DEBUG-IO*", CL_SPECIAL}, +{&Vterminal_io, "*TERMINAL-IO*", CL_SPECIAL}, +{&Vtrace_output, "*TRACE-OUTPUT*", CL_SPECIAL}, +{&siVignore_eof_on_terminal_io, "*IGNORE-EOF-ON-TERMINAL-IO*", SI_SPECIAL}, + +/* format.c */ +{&siVindent_formatted_output, "*INDENT-FORMATTED-OUTPUT*", SI_SPECIAL}, + +/* gbc.c */ +#if 0 && !defined(GBC_BOEHM) +{&siVgc_verbose, "*GC-VERBOSE*", SI_SPECIAL}, +{&siVgc_message, "*GC-MESSAGE*", SI_SPECIAL}, +#endif /* !GBC_BOEHM */ + +/* gfun.c */ +{&siScompute_applicable_methods, "COMPUTE-APPLICABLE-METHODS", SI_ORDINARY}, +{&siScompute_effective_method, "COMPUTE-EFFECTIVE-METHOD", SI_ORDINARY}, +{&siSgeneric_function_method_combination, "GENERIC-FUNCTION-METHOD-COMBINATION", SI_ORDINARY}, +{&siSgeneric_function_method_combination_args, "GENERIC-FUNCTION-METHOD-COMBINATION-ARGS", SI_ORDINARY}, + +/* hash.c */ +{&Seq, "EQ", CL_ORDINARY}, +{&Seql, "EQL", CL_ORDINARY}, +{&Sequal, "EQUAL", CL_ORDINARY}, + +/* instance.c */ +{&Sprint_object, "PRINT-OBJECT", CL_ORDINARY}, + +/* lex.c */ +{&Smacro, "MACRO", CL_ORDINARY}, +{&siSsymbol_macro, "SYMBOL-MACRO", SI_ORDINARY}, +{&Stag, "TAG", CL_ORDINARY}, + +/* load.c */ +{&Vload_verbose, "*LOAD-VERBOSE*", CL_SPECIAL}, +#ifdef PDE +{&siVsource_pathname, "*SOURCE-PATHNAME*", CL_SPECIAL}, +#endif +#ifdef RSYM +{&siVsymbol_table, "*SYMBOL-TABLE*", CL_SPECIAL}, +#endif + +/* lwp.c */ +#ifdef THREADS +{&Srunning, "RUNNING", CL_ORDINARY}, +{&Ssuspended, "SUSPENDED", CL_ORDINARY}, +{&Swaiting, "WAITING", CL_ORDINARY}, +{&Sstopped, "STOPPED", CL_ORDINARY}, +{&Sdead, "DEAD", CL_ORDINARY}, +{&siSthread_top_level, "THREAD-TOP-LEVEL", SI_ORDINARY}, +#endif + +/* macros.c */ +{&Vmacroexpand_hook, "*MACROEXPAND-HOOK*", CL_SPECIAL}, +{&siSexpand_defmacro, "EXPAND-DEFMACRO", SI_ORDINARY}, +{&siVinhibit_macro_special, "*INHIBIT-MACRO-SPECIAL*", SI_SPECIAL}, + +/* main.c */ +{&siVsystem_directory, "*SYSTEM-DIRECTORY*", SI_SPECIAL}, +{&Vfeatures, "*FEATURES*", CL_SPECIAL}, + +/* num_rand.c */ +{&Vrandom_state, "*RANDOM-STATE*", CL_SPECIAL}, + +/* package.c */ +{&Vpackage, "*PACKAGE*", CL_SPECIAL}, + +/* pathname.c */ +{&Vdefault_pathname_defaults, "*DEFAULT-PATHNAME-DEFAULTS*", CL_SPECIAL}, + +/* print.c */ +{&Vprint_escape, "*PRINT-ESCAPE*", CL_SPECIAL}, +{&Vprint_pretty, "*PRINT-PRETTY*", CL_SPECIAL}, +{&Vprint_circle, "*PRINT-CIRCLE*", CL_SPECIAL}, +{&Vprint_base, "*PRINT-BASE*", CL_SPECIAL}, +{&Vprint_radix, "*PRINT-RADIX*", CL_SPECIAL}, +{&Vprint_case, "*PRINT-CASE*", CL_SPECIAL}, +{&Vprint_gensym, "*PRINT-GENSYM*", CL_SPECIAL}, +{&Vprint_level, "*PRINT-LEVEL*", CL_SPECIAL}, +{&Vprint_length, "*PRINT-LENGTH*", CL_SPECIAL}, +{&Vprint_array, "*PRINT-ARRAY*", CL_SPECIAL}, +{&siSpretty_print_format, "PRETTY-PRINT-FORMAT", SI_ORDINARY}, +{&siSsharp_exclamation, "#!", SI_ORDINARY}, +{&siVprint_package, "*PRINT-PACKAGE*", SI_SPECIAL}, +{&siVprint_structure, "*PRINT-STRUCTURE*", SI_SPECIAL}, +#ifdef CLOS +{&Sstream_write_char, "STREAM-WRITE-CHAR", CL_ORDINARY}, +{&Sstream_write_string, "STREAM-WRITE-STRING", CL_ORDINARY}, +{&Sstream_fresh_line, "STREAM-FRESH-LINE", CL_ORDINARY}, +{&Sstream_clear_output, "STREAM-CLEAR-OUTPUT", CL_ORDINARY}, +{&Sstream_force_output, "STREAM-FORCE-OUTPUT", CL_ORDINARY}, +#endif + +/* profile.c */ +#ifdef PROFILE +{&sSAprofile_arrayA, "*PROFILE-ARRAY*", SI_SPECIAL}, +#endif PROFILE + +/* read.c */ +{&Vreadtable, "*READTABLE*", CL_SPECIAL}, +{&Vread_default_float_format, "*READ-DEFAULT-FLOAT-FORMAT*", CL_SPECIAL}, +{&Vread_base, "*READ-BASE*", CL_SPECIAL}, +{&Vread_suppress, "*READ-SUPPRESS*", CL_SPECIAL}, +{&siSsharp_comma, "#,", SI_ORDINARY}, +#ifdef CLOS +{&Sstream_read_line, "STREAM-READ-LINE", CL_ORDINARY}, +{&Sstream_read_char, "STREAM-READ-CHAR", CL_ORDINARY}, +{&Sstream_unread_char, "STREAM-UNREAD-CHAR", CL_ORDINARY}, +{&Sstream_peek_char, "STREAM-PEEK-CHAR", CL_ORDINARY}, +{&Sstream_listen, "STREAM-LISTEN", CL_ORDINARY}, +{&Sstream_clear_input, "STREAM-CLEAR-INPUT", CL_ORDINARY}, +#endif + +/* structure.c */ +{&siSstructure_print_function, "STRUCTURE-PRINT-FUNCTION", SI_ORDINARY}, +{&siSstructure_slot_descriptions, "STRUCTURE-SLOT-DESCRIPTIONS", SI_ORDINARY}, +#ifndef CLOS +{&siSstructure_include, "STRUCTURE-INCLUDE", SI_ORDINARY}, +#else +{&Sstructure_object, "STRUCTURE-OBJECT", CL_ORDINARY}, +#endif + +/* symbol.c */ +{&siSpname, "PNAME", SI_ORDINARY}, +{&Vgensym_counter, "*GENSYM-COUNTER*", CL_SPECIAL}, + +/* toplevel.c */ +{&Sdeclare, "DECLARE", CL_ORDINARY}, +{&Scompile, "COMPILE", CL_ORDINARY}, +{&Sload, "LOAD", CL_ORDINARY}, +{&Seval, "EVAL", CL_ORDINARY}, +{&Sprogn, "PROGN", CL_ORDINARY}, +{&Swarn, "WARN", CL_ORDINARY}, +{&Stypep, "TYPEP", CL_ORDINARY}, + +/* typespec.c */ +{&Squote, "QUOTE", CL_ORDINARY}, +{&Slambda, "LAMBDA", CL_ORDINARY}, +{&Sspecial, "SPECIAL", CL_ORDINARY}, +{&St, "T", CL_ORDINARY}, +{&Snil, "NIL", CL_ORDINARY}, +{&Scommon, "COMMON", CL_ORDINARY}, +{&Ssequence, "SEQUENCE", CL_ORDINARY}, +{&Snull, "NULL", CL_ORDINARY}, +{&Scons, "CONS", CL_ORDINARY}, +{&Slist, "LIST", CL_ORDINARY}, +{&Ssymbol, "SYMBOL", CL_ORDINARY}, +{&Sarray, "ARRAY", CL_ORDINARY}, +{&Svector, "VECTOR", CL_ORDINARY}, +{&Sbit_vector, "BIT-VECTOR", CL_ORDINARY}, +{&Sstring, "STRING", CL_ORDINARY}, +{&Ssimple_array, "SIMPLE-ARRAY", CL_ORDINARY}, +{&Ssimple_vector, "SIMPLE-VECTOR", CL_ORDINARY}, +{&Ssimple_string, "SIMPLE-STRING", CL_ORDINARY}, +{&Ssimple_bit_vector, "SIMPLE-BIT-VECTOR", CL_ORDINARY}, +{&Sfunction, "FUNCTION", CL_ORDINARY}, +{&Spathname, "PATHNAME", CL_ORDINARY}, +{&Slogical_pathname, "LOGICAL-PATHNAME", CL_ORDINARY}, +{&Scharacter, "CHARACTER", CL_ORDINARY}, +{&Sbase_char, "BASE-CHAR", CL_ORDINARY}, +{&Sextended_char, "EXTENDED-CHAR", CL_ORDINARY}, +{&Scompiled_function, "COMPILED-FUNCTION", CL_ORDINARY}, +{&Snumber, "NUMBER", CL_ORDINARY}, +{&Sreal, "REAL", CL_ORDINARY}, +{&Srational, "RATIONAL", CL_ORDINARY}, +{&Sfloat, "FLOAT", CL_ORDINARY}, +{&Sinteger, "INTEGER", CL_ORDINARY}, +{&Sratio, "RATIO", CL_ORDINARY}, +{&Sshort_float, "SHORT-FLOAT", CL_ORDINARY}, +{&Sstandard_char, "STANDARD-CHAR", CL_ORDINARY}, +{&Sfixnum, "FIXNUM", CL_ORDINARY}, +{&Scomplex, "COMPLEX", CL_ORDINARY}, +{&Ssingle_float, "SINGLE-FLOAT", CL_ORDINARY}, +{&Spackage, "PACKAGE", CL_ORDINARY}, +{&Sbignum, "BIGNUM", CL_ORDINARY}, +{&Srandom_state, "RANDOM-STATE", CL_ORDINARY}, +{&Sdouble_float, "DOUBLE-FLOAT", CL_ORDINARY}, +{&Sstream, "STREAM", CL_ORDINARY}, +{&Sbit, "BIT", CL_ORDINARY}, +{&Sreadtable, "READTABLE", CL_ORDINARY}, +{&Slong_float, "LONG-FLOAT", CL_ORDINARY}, +{&Shash_table, "HASH-TABLE", CL_ORDINARY}, +{&Ssigned_char, "SIGNED-CHAR", CL_ORDINARY}, +{&Sunsigned_char, "UNSIGNED-CHAR", CL_ORDINARY}, +{&Ssigned_short, "SIGNED-SHORT", CL_ORDINARY}, +{&Sunsigned_short, "UNSIGNED-SHORT", CL_ORDINARY}, +#ifdef CLOS +{&Sinstance, "INSTANCE", CL_ORDINARY}, +{&Sdispatch_function, "DISPATCH-FUNCTION", CL_ORDINARY}, +{&Sstructure, "STRUCTURE", CL_ORDINARY}, +#endif +{&Ssatisfies, "SATISFIES", CL_ORDINARY}, +{&Smember, "MEMBER", CL_ORDINARY}, +{&Snot, "NOT", CL_ORDINARY}, +{&Sor, "OR", CL_ORDINARY}, +{&Sand, "AND", CL_ORDINARY}, +{&Svalues, "VALUES", CL_ORDINARY}, +{&Smod, "MOD", CL_ORDINARY}, +{&Ssigned_byte, "SIGNED-BYTE", CL_ORDINARY}, +{&Sunsigned_byte, "UNSIGNED-BYTE", CL_ORDINARY}, +{&SX, "*", CL_ORDINARY}, +{&Splusp, "PLUSP", CL_ORDINARY}, +{&Skeyword, "KEYWORD", CL_ORDINARY}, +#ifdef THREADS +{&Scont, "CONT", CL_ORDINARY}, +{&Sthread, "THREAD", CL_ORDINARY}, +#endif +#ifdef LOCATIVE +{&Slocative, "LOCATIVE", CL_ORDINARY}, +#endif +{&Ssubtypep, "SUBTYPEP", CL_ORDINARY}, + +/* unify.c */ +#ifdef LOCATIVE +{&Ssetq, "SETQ", CL_ORDINARY}, +{&Sunify_slot, "UNIFY-SLOT", CL_ORDINARY}, +#endif + +{NULL, (const char*)NULL, CL_ORDINARY}}; + +void +init_all_symbols(void) { + const struct symbol_info *s = all_symbols; + cl_object *loc; + + /* This must keep the garbage collector happy */ + for (s = all_symbols; s->name != NULL; s++) + *(s->loc) = OBJNULL; + + for (s = all_symbols; s->name != NULL; s++) { + loc = s->loc; + switch (s->type) { + case CL_ORDINARY: + *loc = make_ordinary(s->name); + break; + case CL_SPECIAL: + *loc = make_special(s->name, Cnil); + break; + case SI_ORDINARY: + *loc = make_si_ordinary(s->name); + break; + case SI_SPECIAL: + *loc = make_si_special(s->name, Cnil); + break; + } + /* register_root(loc);*/ + } +} diff --git a/src/c/new/compiler.d b/src/c/new/compiler.d new file mode 100644 index 000000000..9cbae7526 --- /dev/null +++ b/src/c/new/compiler.d @@ -0,0 +1,2148 @@ +/* + compiler.c -- Bytecode compiler +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +/********************* EXPORTS *********************/ + +cl_object siSlambda_block; +cl_object Sdeclare; +cl_object Sdefun; +cl_object Scompile, Sload, Seval, Sprogn, Swarn, Stypep, Sotherwise; +cl_object Kexecute, Kcompile_toplevel, Kload_toplevel; +cl_object siVinhibit_macro_special; + +cl_object SAoptional; +cl_object SArest; +cl_object SAkey; +cl_object SAallow_other_keys; +cl_object SAaux; + +cl_object Kallow_other_keys; + +cl_object bytecodes; + +/********************* PRIVATE ********************/ + +static cl_index asm_begin(void); +static cl_object asm_end(cl_index); +static void asm_clear(cl_index); +static void asm_grow(void); +static void asm1(register cl_object op); +static void asm_op(register int n); +static void asm_list(register cl_object l); +static void asmn(int narg, ...); +static void asm_at(register cl_index where, register cl_object what); +static cl_index asm_jmp(register int op); +static void asm_complete(register int op, register cl_index original); +static cl_index current_pc(); +static void set_pc(cl_index pc); +static cl_object asm_ref(register cl_index where); + +static void c_and(cl_object args); +static void c_block(cl_object args); +static void c_case(cl_object args); +static void c_catch(cl_object args); +static void c_cond(cl_object args); +static void c_do(cl_object args); +static void c_doa(cl_object args); +static void c_dolist(cl_object args); +static void c_dotimes(cl_object args); +static void c_eval_when(cl_object args); +static void c_flet(cl_object args); +static void c_function(cl_object args); +static void c_go(cl_object args); +static void c_if(cl_object args); +static void c_labels(cl_object args); +static void c_let(cl_object args); +static void c_leta(cl_object args); +static void c_macrolet(cl_object args); +static void c_multiple_value_bind(cl_object args); +static void c_multiple_value_call(cl_object args); +static void c_multiple_value_prog1(cl_object args); +static void c_multiple_value_setq(cl_object args); +static void c_nth_value(cl_object args); +static void c_or(cl_object args); +static void c_progv(cl_object args); +static void c_psetq(cl_object args); +static void c_values(cl_object args); +static void c_setq(cl_object args); +static void c_return(cl_object args); +static void c_return_from(cl_object args); +static void c_symbol_macrolet(cl_object args); +static void c_tagbody(cl_object args); +static void c_throw(cl_object args); +static void c_unless(cl_object args); +static void c_unwind_protect(cl_object args); +static void c_when(cl_object args); +static void compile_body(cl_object args); +static void compile_form(cl_object args, bool push); + +/* -------------------- SAFE LIST HANDLING -------------------- */ + +static cl_object +pop(cl_object *l) { + cl_object head, list = *l; + if (ATOM(list)) + FEerror("Error parsing special form",0); + head = CAR(list); + *l = CDR(list); + return head; +} + +static cl_object +pop_maybe_nil(cl_object *l) { + cl_object head, list = *l; + if (list == Cnil) + return Cnil; + if (ATOM(list)) + FEerror("Error parsing special form",0); + head = CAR(list); + *l = CDR(list); + return head; +} + +/* ------------------------------ ASSEMBLER ------------------------------ */ + +static cl_index +asm_begin(void) { + /* Save beginning of bytecodes for this session */ + return current_pc(); +} + +static void +asm_clear(cl_index beginning) { + cl_index i; + /* Remove data from this session */ + bytecodes->vector.fillp = beginning; +} + +static cl_object +asm_end(cl_index beginning) { + cl_object new_bytecodes; + cl_index length, bytes, i; + + /* Save bytecodes from this session in a new vector */ + length = current_pc() - beginning; + bytes = length * sizeof(cl_object); + new_bytecodes = alloc_object(t_bytecodes); + new_bytecodes->bytecodes.lex = Cnil; + new_bytecodes->bytecodes.data = alloc(bytes); + new_bytecodes->bytecodes.size = length; + memcpy(new_bytecodes->bytecodes.data, + &bytecodes->vector.self.t[beginning], + bytes); + + asm_clear(beginning); + return new_bytecodes; +} + +static void +asm_grow(void) { + cl_object *old_data = bytecodes->vector.self.t; + cl_index old_size = bytecodes->vector.fillp; + bytecodes->vector.dim += 128; + array_allocself(bytecodes); + memcpy(bytecodes->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +asm1(register cl_object op) { + int where = bytecodes->vector.fillp; + if (where >= bytecodes->vector.dim) + asm_grow(); + bytecodes->vector.self.t[where] = op; + bytecodes->vector.fillp++; +} + +static void +asm_op(register int n) { + asm1(MAKE_FIXNUM(n)); +} + +static void +asm_op2(register int code, register cl_fixnum n) { + cl_object op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEerror("Argument to bytecode is too large", 0); + else + asm1(new_op); +} + +static inline cl_object +make_op(int code) { + return MAKE_FIXNUM(code); +} + +static cl_object +make_op2(int code, cl_fixnum n) { + cl_object volatile op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEerror("Argument to bytecode is too large", 0); + return new_op; +} + +static void +asm_insert(cl_fixnum where, cl_object op) { + cl_fixnum end = bytecodes->vector.fillp; + if (where > end) + FEerror("asm1_insert: position out of range", 0); + if (end >= bytecodes->vector.dim) + asm_grow(); + memmove(&bytecodes->vector.self.t[where+1], + &bytecodes->vector.self.t[where], + (end - where) * sizeof(cl_object)); + bytecodes->vector.fillp++; + bytecodes->vector.self.t[where] = op; +} + +static void +asm_list(register cl_object l) { + if (ATOM(l)) + asm1(l); + while(!endp(l)) { + asm1(CAR(l)); + l = CDR(l); + } +} + +static void +asmn(int narg, ...) { + va_list args; + + va_start(args, narg); + while (narg-- > 0) + asm1(va_arg(args, cl_object)); +} + +static void +asm_at(register cl_index where, register cl_object what) { + if (where > bytecodes->vector.fillp) + FEerror("Internal error at asm_at()",0); + bytecodes->vector.self.t[where] = what; +} + +static cl_index +asm_block(void) { + cl_index output; + output = current_pc(); + asm1(MAKE_FIXNUM(0)); + return output; +} + +static cl_index +asm_jmp(register int op) { + cl_index output = current_pc(); + asm_op(op); + return output; +} + +static void +asm_complete(register int op, register cl_index original) { + cl_fixnum delta = current_pc() - original; + cl_object code = asm_ref(original); + cl_object new_code = SET_OPARG(code, delta); + if (code != MAKE_FIXNUM(op)) + FEerror("Non matching codes in ASM-COMPLETE2", 0); + else if (delta < -MAX_OPARG || delta > MAX_OPARG) + FEerror("Too large jump", 0); + else + asm_at(original, new_code); +} + +static cl_index +current_pc(void) { + return bytecodes->vector.fillp; +} + +static void +set_pc(cl_index pc) { + bytecodes->vector.fillp = pc; +} + +static cl_object +asm_ref(register cl_index n) { + return bytecodes->vector.self.t[n]; +} + +/* ------------------------------ COMPILER ------------------------------ */ + +typedef struct { + cl_object symbol; + const char *const name; + void (*compiler)(cl_object); +} compiler_record; + +static compiler_record database[] = { + {OBJNULL, "AND", c_and}, + {OBJNULL, "BLOCK", c_block}, + {OBJNULL, "CASE", c_case}, + {OBJNULL, "CATCH", c_catch}, + {OBJNULL, "COND", c_cond}, + {OBJNULL, "DO", c_do}, + {OBJNULL, "DO*", c_doa}, + {OBJNULL, "DOLIST", c_dolist}, + {OBJNULL, "DOTIMES", c_dotimes}, + {OBJNULL, "EVAL-WHEN", c_eval_when}, + {OBJNULL, "FLET", c_flet}, + {OBJNULL, "FUNCTION", c_function}, + {OBJNULL, "GO", c_go}, + {OBJNULL, "IF", c_if}, + {OBJNULL, "LABELS", c_labels}, + {OBJNULL, "LET", c_let}, + {OBJNULL, "LET*", c_leta}, + {OBJNULL, "MACROLET", c_macrolet}, + {OBJNULL, "MULTIPLE-VALUE-BIND", c_multiple_value_bind}, + {OBJNULL, "MULTIPLE-VALUE-CALL", c_multiple_value_call}, + {OBJNULL, "MULTIPLE-VALUE-PROG1", c_multiple_value_prog1}, + {OBJNULL, "MULTIPLE-VALUE-SETQ", c_multiple_value_setq}, + {OBJNULL, "NTH-VALUE", c_nth_value}, + {OBJNULL, "OR", c_or}, + {OBJNULL, "PROGN", compile_body}, + {OBJNULL, "PROGV", c_progv}, + {OBJNULL, "PSETQ", c_psetq}, + {OBJNULL, "RETURN", c_return}, + {OBJNULL, "RETURN-FROM", c_return_from}, + {OBJNULL, "SETQ", c_setq}, + {OBJNULL, "TAGBODY", c_tagbody}, + {OBJNULL, "THROW", c_throw}, + {OBJNULL, "UNWIND-PROTECT", c_unwind_protect}, + {OBJNULL, "UNLESS", c_unless}, + {OBJNULL, "VALUES", c_values}, + {OBJNULL, "WHEN", c_when}, + {OBJNULL, "", c_when} +}; + +/* ----------------- LEXICAL ENVIRONMENT HANDLING -------------------- */ + +static void +c_register_var(register cl_object var, bool special) +{ + CAR(lex_env) = CONS(CONS(var, special? Sspecial : Cnil), CAR(lex_env)); +} + +static bool +special_variablep(register cl_object var, register cl_object specials) +{ + return ((var->symbol.stype == stp_special) || member_eq(var, specials)); +} + +static void +c_pbind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEerror("The object ~A is not a valid variable name", 1, var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_PBINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_PBIND); + } + asm1(var); +} + +static void +c_bind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEerror("The object ~A is not a valid variable name", 1, var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_BINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_BIND); + } + asm1(var); +} + +static void +compile_setq(int op, cl_object var) +{ + cl_object ndx; + + if (!SYMBOLP(var)) + FEerror("SETQ: ~A is not a symbol", 1, var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm_op(op); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEerror("SETQ: Cannot change the value of the constant ~A", 1,var); + else if (op == OP_SETQ) + asm_op(OP_SETQS); /* Special variable */ + else + asm_op(OP_PSETQS); /* Special variable */ + asm1(var); +} + +static void +bind_tag(cl_object tag) +{ + CDR(lex_env) = CONS(list(3, tag, Stag, Cnil), CDR(lex_env)); +} + +static bool +reference_tag(cl_object tag) +{ + cl_object l; + bool non_local = FALSE; + + for (l = CDR(lex_env); !endp(l); l = CDR(l)) { + cl_object record = CAR(l); + if (ATOM(record)) + non_local = TRUE; + else if (CAR(record) == Ct && CDR(record) == Cnil) + non_local = TRUE; + else if (eql(CAR(record), tag) && CADR(record) == Stag) { + cl_object mark; + if (non_local) + mark = Ct; + else + mark = MAKE_FIXNUM(current_pc()); + CADDR(record) = nconc(CADDR(record), CONS(mark, Cnil)); + return non_local; + } + } + FEerror("Reference to unknown tag ~S", 1, tag); +} + +/* -------------------- THE COMPILER -------------------- */ + +static void +c_and(cl_object args) { + if (Null(args)) { + asm1(Ct); + return; + } else if (ATOM(args)) { + FEerror("Wrong type of argument to AND ~S", 1, args); + } else { + compile_form(pop(&args),FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JNIL); + c_and(args); + asm_complete(OP_JNIL, label); + } + } +} + +/* + The OP_BLOCK operator encloses several forms within a block + named BLOCK_NAME, thus catching any OP_RETFROM whose argument + matches BLOCK_NAME. The end of this block is marked both by + the OP_EXIT operator and the LABELZ which is packed within + the OP_BLOCK operator. + + [OP_BLOCK + labelz] + block_name + .... + OP_EXIT + labelz: ... +*/ + +static void +c_block(cl_object body) { + cl_object name = pop(&body); + cl_index labelz = asm_jmp(OP_BLOCK); + if (!SYMBOLP(name)) + FEerror("Not a valid BLOCK name: ~S", 1, name); + asm1(name); + compile_body(body); + asm_op(OP_EXIT); + asm_complete(OP_BLOCK, labelz); +} + +/* + There are several ways to invoke functions and to handle the + output arguments. These are + + [OP_CALL + nargs] + function_name + + [OP_PCALL + nargs] + function_name + + [OP_FCALL + nargs] + + [OP_PFCALL + nargs] + + OP_CALL and OP_FCALL leave all arguments in the VALUES() array, + while OP_PCALL and OP_PFCALL leave the first argument in the + stack. + + OP_CALL and OP_PCALL use the following symbol to retrieve the + function, while OP_FCALL and OP_PFCALL use the value in VALUES(0). + */ +static void +c_call(cl_object args, bool push) { + cl_object name; + cl_index nargs; + + name = pop(&args); + for (nargs = 0; !endp(args); nargs++) { + compile_form(pop(&args),TRUE); + } + if (ATOM(name)) { + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(name); + } else if (CAR(name) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(name))); + asm_op2(push? OP_PFCALL : OP_FCALL, nargs); + } else { + cl_object aux = setf_namep(name); + if (aux == OBJNULL) + FEerror("Invalid function name ~S", 1, name); + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(aux); + } +} + +static void +perform_c_case(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label1, label2; + + if (Null(args)) { + asm_op(OP_NOP); + return; + } + + clause = pop(&args); + if (ATOM(clause)) + FEerror("~S is an illegal CASE clause.",1,clause); + test = pop(&clause); + if (Sotherwise == test || test == Ct) { + compile_body(clause); + } else { + cl_index labeln, labelz; + if (CONSP(test)) { + cl_index n = length(test); + while (n > 1) { + cl_object v = pop(&test); + cl_fixnum jump = (n--) * 2; + asm_op2(OP_JEQ, jump); + asm1(v); + } + test = CAR(test); + } + labeln = asm_jmp(OP_JNEQ); + asm1(test); + compile_body(clause); + labelz = asm_jmp(OP_JMP); + asm_complete(OP_JNEQ, labeln); + perform_c_case(args); + asm_complete(OP_JMP, labelz); + } +} + +static void +c_case(cl_object clause) { + compile_form(pop(&clause), FALSE); + perform_c_case(clause); +} + +/* + The OP_CATCH takes the object in VALUES(0) and uses it to catch + any OP_THROW operation which uses that value as argument. If a + catch occurs, or when all forms have been properly executed, it + jumps to LABELZ. LABELZ is packed within the OP_CATCH operator. + [OP_CATCH + labelz] + ... + "forms to be caught" + ... + OP_EXIT + labelz: ... +*/ + +static void +c_catch(cl_object args) { + cl_index labelz; + + /* Compile evaluation of tag */ + compile_form(pop(&args), FALSE); + + /* Compile jump point */ + labelz = asm_jmp(OP_CATCH); + + /* Compile body of CATCH */ + compile_body(args); + asm_op(OP_EXIT); + asm_complete(OP_CATCH, labelz); +} + +/* + There are three operators which perform explicit jumps, but + almost all other operators use labels in one way or + another. + + 1) Jumps are always relative to the place where the jump label + is retrieved so that if the label is in vector[0], then the + destination is roughly vector + vector[0]. + + 2) There are two types of labels, "packed labels" and "simple + labels". The first ones are packed in the upper bits of an + operator so that + destination = vector + vector[0]>>16 + Simple labels take the whole word and thus + destination = vector + fix(vector[0]) + + 3) The three jump forms are + + [OP_JMP + label] ; Unconditional jump + [OP_JNIL + label] ; Jump if VALUES(0) == Cnil + [OP_JT + label] ; Jump if VALUES(0) != Cnil + + It is important to remark that both OP_JNIL and OP_JT truncate + the values stack, so that always NValues = 1 after performing + any of these operations. +*/ +static void +c_cond(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label_nil, label_exit; + + clause = pop(&args); + if (ATOM(clause)) + FEerror("~S is an illegal COND clause.",1,clause); + test = pop(&clause); + if (Ct == test) { + /* Default sentence. If no forms, just output T. */ + if (Null(clause)) + compile_form(Ct, FALSE); + else + compile_body(clause); + } else { + /* Compile the test. If no more forms, just output + the first value (this is guaranteed by OP_JNIL */ + compile_form(test, FALSE); + label_nil = asm_jmp(OP_JNIL); + if (!Null(clause)) + compile_body(clause); + if (Null(args)) + asm_complete(OP_JNIL, label_nil); + else { + label_exit = asm_jmp(OP_JMP); + asm_complete(OP_JNIL, label_nil); + c_cond(args); + asm_complete(OP_JMP, label_exit); + } + } +} + +/* The OP_DO operator saves the lexical environment and establishes + a NIL block to execute the enclosed forms, which are typically + like the ones shown below. At the exit of the block, either by + means of a OP_RETFROM jump or because of normal termination, + the lexical environment is restored, and all bindings undone. + + [OP_DO + labelz] + labelz + ... ; bindings + labelb: ... ; body + ... ; stepping forms + labelt: ... ; test form + [JNIL + label] + ... ; output form + OP_EXIT + labelz: + +*/ +static void +c_do_doa(int op, cl_object args) { + cl_object bindings, test, specials, body, l; + cl_object stepping = Cnil, vars = Cnil; + cl_index labelb, labelt, labelz; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = pop(&args); + test = pop(&args); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + labelz = asm_jmp(OP_DO); + + /* Compile initial bindings */ + if (length(bindings) == 1) + op = OP_BIND; + for (l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!endp(aux)) + stepping = CONS(CONS(var,pop(&aux)),stepping); + if (!Null(aux)) + FEerror("Not a valid argument to LET ~S.", 1, + args); + } + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + + /* Jump to test */ + labelt = asm_jmp(OP_JMP); + + /* Compile body */ + labelb = current_pc(); + c_tagbody(body); + + /* Compile stepping clauses */ + if (length(stepping) == 1) + op = OP_BIND; + for (vars = Cnil, stepping=nreverse(stepping); !endp(stepping); ) { + cl_object pair = pop(&stepping); + cl_object var = CAR(pair); + cl_object value = CDR(pair); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); + + /* Compile test */ + asm_complete(OP_JMP, labelt); + compile_form(pop(&test), FALSE); + asm_op2(OP_JNIL, labelb - current_pc()); + + /* Compile output clauses */ + compile_body(test); + asm_op(OP_EXIT); + + /* Compile return point of block */ + asm_complete(OP_DO, labelz); + + lex_env = lex_old; +} + + +static void +c_doa(cl_object args) { + c_do_doa(OP_BIND, args); +} + +static void +c_do(cl_object args) { + c_do_doa(OP_PBIND, args); +} + +/* + The OP_DOLIST & OP_DOTIMES operators save the lexical + environment and establishes a NIL block to execute the + enclosed forms, which iterate over the elements in a list or + over a range of integer numbers. At the exit of the block, + either by means of a OP_RETFROM jump or because of normal + termination, the lexical environment is restored, and all + bindings undone. + + [OP_DOTIMES/OP_DOLIST + labelz] + ... ; bindings + [OP_EXIT + labelo] + ... ; body + ... ; stepping forms + OP_EXIT + labelo: ... ; output form + OP_EXIT + labelz: + + */ + +static void +c_dolist_dotimes(int op, cl_object args) { + cl_object head = pop(&args); + cl_object var = pop(&head); + cl_object list = pop(&head); + cl_object specials, body; + cl_index labelz, labelo; + cl_object lex_old = lex_env; + lex_copy(); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + if (!SYMBOLP(var)) + FEerror("Cannot bind to ~S", 1, var); + + /* Compute list and enter loop */ + compile_form(list, FALSE); + labelz = asm_jmp(op); + + /* Initialize the variable */ + compile_form((op == OP_DOLIST)? Cnil : MAKE_FIXNUM(0), FALSE); + c_bind(var, specials); + labelo = asm_jmp(OP_EXIT); + + /* Variable assignment and iterated body */ + compile_setq(OP_SETQ, var); + c_tagbody(body); + asm_op(OP_EXIT); + + /* Output */ + asm_complete(OP_EXIT, labelo); + if (CDR(head) != Cnil) + FEerror("Too many arguments to output form of DOLIST", 0); + if (Null(head)) + compile_body(Cnil); + else { + compile_setq(OP_SETQ, var); + compile_form(pop(&head), FALSE); + } + asm_op(OP_EXIT); + + /* Exit point for block */ + asm_complete(op, labelz); + + lex_env = lex_old; +} + + +static void +c_dolist(cl_object args) { + c_dolist_dotimes(OP_DOLIST, args); +} + +static void +c_dotimes(cl_object args) { + c_dolist_dotimes(OP_DOTIMES, args); +} + +static void +c_eval_when(cl_object args) { + cl_object situation = pop(&args); + + if (member_eq(Seval, situation) || member_eq(Kexecute, situation)) + compile_body(args); + else + compile_body(Cnil); +} + + +/* + The OP_FLET/OP_FLABELS operators change the lexical environment + to add a few local functions. + + [OP_FLET/OP_FLABELS + nfun] + fun1 + ... + funn + ... + OP_EXIT + labelz: +*/ +static void +c_labels_flet(int op, cl_object args) { + cl_object def_list = pop(&args); + int nfun = length(def_list); + cl_object lex_old = lex_env; + lex_copy(); + + if (nfun == 0) { + compile_body(args); + return; + } + asm_op2(op, nfun); + do { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + asm1(make_lambda(name, definition)); + } while (!endp(def_list)); + compile_body(args); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + + +static void +c_flet(cl_object args) { + c_labels_flet(OP_FLET, args); +} + + +/* + There are two operators that produce functions. The first one + is + OP_FUNCTION + symbol + which takes the function binding of SYMBOL. The second one is + OP_CLOSE + interpreted + which encloses the INTERPRETED function in the current lexical + environment. +*/ +static void +c_function(cl_object args) { + cl_object function = pop(&args); + if (!endp(args)) + FEerror("Too many arguments to FUNCTION", 0); + if (SYMBOLP(function)) { + asm_op(OP_FUNCTION); + asm1(function); + } else if (CONSP(function) && CAR(function) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(function))); + } else if (CONSP(function) && CAR(function) == siSlambda_block) { + cl_object name = CADR(function); + cl_object body = CDDR(function); + asm_op(OP_CLOSE); + asm1(make_lambda(name, body)); + } else + FEerror("No a valid argument to FUNCTION ~S", 1, function); +} + + +static void +c_go(cl_object args) { + cl_object tag = pop(&args); + if (!Null(args)) + FEerror("Too many arguments to GO",0); + if (!reference_tag(tag)) + asm_op(OP_JMP); /* Local tag */ + else { + asm_op(OP_GO); /* Tagbody out of closure */ + asm1(tag); + } +} + + +/* + To get an idea of what goes on + + ... ; test form + JNIL labeln + ... ; form for true case + JMP labelz + ... ; form fro nil case + labelz: +*/ +static void +c_if(cl_object form) { + cl_fixnum label_nil, label_true; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_nil = asm_jmp(OP_JNIL); + + /* Compile THEN clause */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JMP); + + /* Compile ELSE clause */ + asm_complete(OP_JNIL, label_nil); + if (!endp(form)) + compile_form(pop(&form), FALSE); + asm_complete(OP_JMP, label_true); + + if (!Null(form)) + FEerror("Too many arguments to IF form", 0); +} + + +static void +c_labels(cl_object args) { + c_labels_flet(OP_LABELS, args); +} + + +/* + The OP_PUSHENV saves the current lexical environment to allow + several bindings. + OP_PUSHENV + ... ; binding forms + ... ; body + OP_EXIT + + There are four forms which perform bindings + OP_PBIND ; Bind NAME in the lexical env. using + name ; a value from the stack + OP_PBINDS ; Bind NAME as special variable using + name ; a value from the stack + OP_BIND ; Bind NAME in the lexical env. using + name ; VALUES(0) + OP_BINDS ; Bind NAME as special variable using + name ; VALUES(0) + + After a variable has been bound, there are several ways to + refer to it. + + 1) Refer to the n-th variable in the lexical environment + [SYMVAL + n] + + 2) Refer to the value of a special variable or constant + SYMVALS + name + + 3) Push the value of the n-th variable of the lexical environment + [PUSHV + n] + + 4) Push the value of a special variable or constant + PUSHVS + name +*/ + +static void +c_let_leta(int op, cl_object args) { + cl_object bindings, specials, body, l, vars; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = car(args); + siLprocess_declarations(1, CDR(args)); + body = VALUES(1); + specials = VALUES(3); + + /* Optimize some common cases */ + switch(length(bindings)) { + case 0: compile_body(body); return; + case 1: op = OP_BIND; break; + default: + } + + asm_op(OP_PUSHENV); + for (vars=Cnil, l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!Null(aux)) + FEerror("Not a valid argument to LET ~S.", 1, + args); + } + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + compile_body(body); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + +static void +c_let(cl_object args) { + c_let_leta(OP_PBIND, args); +} + +static void +c_leta(cl_object args) { + c_let_leta(OP_BIND, args); +} + +/* + MACROLET + + The current lexical environment is saved. A new one is prepared with + the definitions of these macros, and this environment is used to + compile the body. + */ +static void +c_macrolet(cl_object args) +{ + cl_object def_list, def, name; + int nfun = 0; + cl_object lex_old = lex_env; + lex_copy(); + + /* Pop the list of definitions */ + for (def_list = pop(&args); !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object arglist = pop(&definition); + cl_object macro, function; + macro = funcall(4, siSexpand_defmacro, name, arglist, + definition); + function = make_lambda(name, CDR(macro)); + lex_macro_bind(name, function); + } + compile_body(args); + lex_env = lex_old; +} + + +static void +c_multiple_value_bind(cl_object args) +{ + cl_object vars, value, body, specials; + cl_index save_pc, n; + cl_object lex_old = lex_env; + lex_copy(); + + vars = pop(&args); + value = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + compile_form(value, FALSE); + n = length(vars); + if (n == 0) { + compile_body(body); + } else { + asm_op(OP_PUSHENV); + asm_op2(OP_MBIND, n); + for (vars=reverse(vars); n; n--){ + cl_object var = pop(&vars); + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (special_variablep(var, specials)) { + asm1(MAKE_FIXNUM(1)); + c_register_var(var, TRUE); + } else + c_register_var(var, FALSE); + asm1(var); + } + compile_body(body); + asm_op(OP_EXIT); + } + lex_env = lex_old; +} + + +static void +c_multiple_value_call(cl_object args) { + cl_object name; + + name = pop(&args); + if (endp(args)) { + /* If no arguments, just use ordinary call */ + c_call(list(1, name), FALSE); + return; + } + asm_op(OP_MCALL); + do { + compile_form(pop(&args), FALSE); + asm_op(OP_PUSHVALUES); + } while (!endp(args)); + compile_form(name, FALSE); + asm_op(OP_EXIT); +} + + +static void +c_multiple_value_prog1(cl_object args) { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + asm_op(OP_MPROG1); + compile_body(args); + asm_op(OP_EXIT); + } +} + + +static void +c_multiple_value_setq(cl_object args) { + cl_object orig_vars; + cl_object vars = Cnil; + cl_object temp_vars = Cnil; + cl_object late_assignment = Cnil; + cl_index nvars = 0; + + /* Look for symbol macros, building the list of variables + and the list of late assignments. */ + for (orig_vars = reverse(pop(&args)); !endp(orig_vars); ) { + cl_object aux, v = pop(&orig_vars); + if (!SYMBOLP(v)) + FEerror("Cannot bind ~S", 1, v); + v = macro_expand1(v, CDR(lex_env)); + if (!SYMBOLP(v)) { + aux = v; + v = Lgensym(0); + temp_vars = CONS(v, temp_vars); + late_assignment = CONS(list(3, Ssetf, aux, v), + late_assignment); + } + vars = CONS(v, vars); + nvars++; + } + + if (!Null(temp_vars)) { + asm_op(OP_PUSHENV); + do { + compile_form(Cnil, FALSE); + c_bind(CAR(temp_vars), Cnil); + temp_vars = CDR(temp_vars); + } while (!Null(temp_vars)); + } + + /* Compile values */ + compile_form(pop(&args), FALSE); + if (args != Cnil) + FEerror("Too many arguments to MULTIPLE-VALUE-SETQ",0); + if (nvars == 0) + /* No variables */ + return; + + /* Compile variables */ + asm_op2(OP_MSETQ, nvars); + vars = reverse(vars); + while (nvars--) { + cl_object ndx, var = pop(&vars); + if (!SYMBOLP(var)) + FEerror("MULTIPLE-VALUE-SETQ: ~A is not a symbol", 1, var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm1(var); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEerror("MULTIPLE-VALUE-SETQ: Cannot change the value of the constant ~A", 1,var); + else { + asm1(MAKE_FIXNUM(1)); + asm1(var); + } + } + + /* Assign to symbol-macros */ + if (!Null(late_assignment)) { + compile_body(late_assignment); + asm_op(OP_EXIT); + } +} + + +/* + The OP_NTHVAL operator moves a value from VALUES(ndx) to + VALUES(0). The index NDX is taken from the stack. + + OP_NTHVAL +*/ +static void +c_nth_value(cl_object args) { + compile_form(pop(&args), TRUE); /* INDEX */ + compile_form(pop(&args), FALSE); /* VALUES */ + if (args != Cnil) + FEerror("Too many arguments to NTH-VALUE",0); + asm_op(OP_NTHVAL); +} + + +static void +c_or(cl_object args) { + if (Null(args)) { + asm1(Cnil); + return; + } else if (ATOM(args)) { + FEerror("Wrong type of argument to AND ~S", 1, args); + } else { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JT); + c_or(args); + asm_complete(OP_JT, label); + } + } +} + + +/* + The OP_PROGV operator exectures a set of statements in a lexical + environment that has been extended with special variables. The + list of special variables is taken from the top of the stack, + while the list of values is in VALUES(0). + + ... ; list of variables + OP_PUSH + ... ; list of values + OP_PROGV + ... ; body of progv + OP_EXIT +*/ +static void +c_progv(cl_object args) { + cl_object vars = pop(&args); + cl_object values = pop(&args); + + /* The list of variables is in the stack */ + compile_form(vars, TRUE); + + /* The list of values is in VALUES(0) */ + compile_form(values, FALSE); + + /* The body is interpreted within an extended lexical + environment. However, as all the new variables are + special, the compiler need not take care of them + */ + asm_op(OP_PROGV); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + There are four assignment operators. They are + + 1) Assign VALUES(0) to the lexical variable which occupies the + N-th position + [OP_SETQ + n] + + 2) Assign VALUES(0) to the special variable NAME + OP_SETQS + name + + 3) Pop a value from the stack and assign it to the lexical + variable in the N-th position. + [OP_PSETQ + n] + + 4) Pop a value from the stack and assign it to the special + variable denoted by NAME + OP_PSETQS + name +*/ +static void +c_psetq(cl_object old_args) { + cl_object args = Cnil, vars = Cnil; + bool use_psetf = FALSE; + cl_index nvars = 0; + + /* We have to make sure that non of the variables which + are to be assigned is actually a symbol macro. If that + is the case, we invoke (PSETF ...) to handle the + macro expansions. + */ + while (!endp(old_args)) { + cl_object var = pop(&old_args); + cl_object value = pop(&old_args); + if (!SYMBOLP(var)) + FEerror("Cannot assign to ~a", 1, var); + var = macro_expand1(var, CDR(lex_env)); + if (!SYMBOLP(var)) + use_psetf = TRUE; + args = CONS(var, CONS(value, args)); + nvars++; + } + if (use_psetf) { + compile_form(CONS(Spsetf, args), FALSE); + return; + } + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + vars = CONS(var, vars); + compile_form(value, TRUE); + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); +} + + +/* + The OP_RETFROM operator returns from a block using the objects + in VALUES() as output values. + + ... ; output form + OP_RETFROM + tag ; object which names the block +*/ +static void +c_return(cl_object stmt) { + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + asm1(Cnil); + if (stmt != Cnil) + FEerror("Too many arguments to RETURN", 0); +} + + +static void +c_return_from(cl_object stmt) { + cl_object name = pop(&stmt); + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + if (!SYMBOLP(name)) + FEerror("Not a valid return tag ~S", 1, name); + asm1(name); + if (stmt != Cnil) + FEerror("Too many arguments to RETURN-FROM", 0); +} + + +static void +c_setq(cl_object args) { + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S", 1, var); + var = macro_expand1(var, CDR(lex_env)); + if (SYMBOLP(var)) { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } else { + compile_form(list(3, Ssetf, var, value), FALSE); + } + } +} + + +static void +c_symbol_macrolet(cl_object args) +{ + cl_object def_list, def, name, specials, body; + cl_object lex_old = lex_env; + int nfun = 0; + + /* Set a new lexical environment where we will bind + our macrology */ + lex_copy(); + + def_list = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + /* Scan the list of definitions */ + for (; !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object expansion = pop(&definition); + cl_object arglist = list(2, Lgensym(0), Lgensym(0)); + cl_object function; + if (special_variablep(name, specials)) + FEerror("Symbol ~A cannot be declared special and appear in a SYMBOL-MACROLET", 1, name); + definition = list(2, arglist, list(2, Squote, expansion)); + function = make_lambda(name, definition); + lex_symbol_macro_bind(name, function); + } + compile_body(body); + lex_env = lex_old; +} + +static void +c_tagbody(cl_object args) +{ + int i, nt; + cl_fixnum label0, labelz; + cl_object body, tag_list; + cl_object lex_old = lex_env; + lex_copy(); + + /* count and register the tags */ + for (nt = 0, tag_list = Cnil, body = args; !endp(body); body = CDR(body)) { + cl_object form = CAR(body); + int type = type_of(form); + if (type == t_symbol || type == t_fixnum || type == t_bignum) { + tag_list = CONS(list(3, form, Stag, Cnil), tag_list); + nt += 1; + } + } + if (nt == 0) { + compile_body(args); + return; + } + label0 = current_pc(); + CDR(lex_env) = nconc(nreverse(tag_list), CDR(lex_env)); + + /* + * We compile the body, storing the address of each label. + */ + for (tag_list = CDR(lex_env), body = args; !endp(body); body = CDR(body)) { + cl_object form = CAR(body); + int type = type_of(form); + if (type == t_symbol || type == t_fixnum || type == t_bignum) { + /* Each label points to a place in the bytecodes + stack. This point is registered at the beginning of + the tag list. */ + cl_object pc = MAKE_FIXNUM(current_pc()); + cl_object tag = CAR(tag_list); + cl_object relocation = CADDR(tag); + CADDR(tag) = CONS(pc, relocation); + tag_list = CDR(tag_list); + } else if (CONSP(form)) { + /* Since the output of all forms is ignored, we + need only compile forms which are not atoms */ + compile_form(form, FALSE); + } + } + /* + * Each (GO ...) form leads to either a local jump, or a jump + * out of a closure. In this loop we fix the destination of those + * local jumps... + */ + for (i = 0, tag_list = Cnil; nt; nt--, CDR(lex_env) = CDDR(lex_env)) { + cl_object tag = CADR(lex_env); + cl_object tag_name = CAR(tag); + cl_object relocation = CADDR(tag); + cl_fixnum pc = fix(pop(&relocation)); + while (!endp(relocation)) { + cl_object jump = pop(&relocation); + if (FIXNUMP(jump)) { + cl_fixnum pc_orig = fix(jump); + asm_at(pc_orig, make_op2(OP_JMP, pc - pc_orig)); + continue; + } + tag_list = nconc(tag_list, + list(2, tag_name, MAKE_FIXNUM(pc))); + i++; + } + } + /* + * ...and in this loop we keep a record of the tags that were + * referenced by nonlocal jumps. This implies inserting an OP_TAGBODY + * operand with its relocation table at LABEL0. + */ + if (!i) + compile_body(Cnil); + else { + cl_fixnum delta = 1 + 2*i; + cl_fixnum label; + asm_op(OP_EXIT); + asm_insert(label0, make_op2(OP_TAGBODY, i)); + while (!endp(tag_list)) { + cl_object name = pop(&tag_list); + cl_fixnum pc = fix(pop(&tag_list)) + delta; + asm_insert(label0, name); label0++; + asm_insert(label0, MAKE_FIXNUM(pc - label0)); label0++; + } + } +} + + +/* + The OP_THROW jumps to an enclosing OP_CATCH whose tag + matches the one of the throw. The tag is taken from the + stack, while the output values are left in VALUES(). +*/ +static void +c_throw(cl_object stmt) { + /* FIXME! Do we apply the right protocol here? */ + cl_object tag = pop(&stmt); + cl_object form = pop(&stmt); + if (stmt != Cnil) + FEerror("Too many argumnents to THROW",0); + compile_form(tag, TRUE); + compile_form(form, FALSE); + asm_op(OP_THROW); +} + + +static void +c_unless(cl_object form) { + cl_fixnum label_true, label_false; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JT); + + /* Compile body */ + compile_body(form); + label_false = asm_jmp(OP_JMP); + asm_complete(OP_JT, label_true); + + /* When test failed, output NIL */ + asm1(Cnil); + asm_complete(OP_JMP, label_false); +} + + +static void +c_unwind_protect(cl_object args) { + cl_index label = asm_jmp(OP_UNWIND); + + /* Compile form to be protected */ + compile_form(pop(&args), FALSE); + asm_op(OP_EXIT); + + /* Compile exit clause */ + asm_complete(OP_UNWIND, label); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + The OP_VALUES moves N values from the stack to VALUES(). + + [OP_VALUES + n] +*/ +static void +c_values(cl_object args) { + int n = 0; + + while (!endp(args)) { + compile_form(pop_maybe_nil(&args), TRUE); + n++; + } + asm_op2(OP_VALUES, n); +} + + +static void +c_when(cl_object form) { + cl_fixnum label; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label = asm_jmp(OP_JNIL); + + /* Compile body */ + compile_body(form); + asm_complete(OP_JNIL, label); +} + + +static void +compile_form(cl_object stmt, bool push) { + compiler_record *l; + cl_object function; + cl_object macro; + + /* FIXME! We should protect this region with error handling */ + BEGIN: + /* + * First try with variable references and quoted constants + */ + if (ATOM(stmt)) { + if (SYMBOLP(stmt)) { + if (push) asm_op(OP_PUSHV); + asm1(stmt); + goto OUTPUT; + } + QUOTED: + if (push) + asm_op(OP_PUSHQ); + else if (FIXNUMP(stmt) || SYMBOLP(stmt)) + asm_op(OP_QUOTE); + asm1(stmt); + goto OUTPUT; + } + LIST: + /* + * Next try with special forms. + */ + function = CAR(stmt); + if (!SYMBOLP(function)) + goto ORDINARY_CALL; + if (function == Squote) { + stmt = CDR(stmt); + if (CDR(stmt) != Cnil) + FEerror("Too many arguments to QUOTE",0); + stmt = CAR(stmt); + goto QUOTED; + } + for (l = database; l->symbol != OBJNULL; l++) + if (l->symbol == function) { + (*(l->compiler))(CDR(stmt)); + if (push) asm_op(OP_PUSH); + goto OUTPUT; + } + /* + * Next try to macroexpand + */ + { + cl_object new_stmt = macro_expand1(stmt, CDR(lex_env)); + if (new_stmt != stmt){ + stmt = new_stmt; + goto BEGIN; + } + } + if (function->symbol.isform) + FEerror("Found no macroexpander for special form ~S", 1, function); + ORDINARY_CALL: + /* + * Finally resort to ordinary function calls. + */ + c_call(stmt, push); + OUTPUT: +} + + +static void +compile_body(cl_object body) { + if (endp(body)) + asm_op(OP_NOP); + else do { + compile_form(CAR(body), FALSE); + body = CDR(body); + } while (!endp(body)); +} + +/* ----------------------------- PUBLIC INTERFACE ---------------------------- */ + +/* ------------------------------------------------------------ + LAMBDA OBJECTS: An interpreted function is a vector made of + the following components + + #(LAMBDA + {block-name | NIL} + {variable-env | NIL} + {function-env | NIL} + {block-env | NIL} + (list of variables declared special) + Nreq {var}* ; required arguments + Nopt {var value flag}* ; optional arguments + {rest-var NIL} ; rest variable + {T | NIL} ; allow other keys? + Nkey {key var value flag}* ; keyword arguments + Naux {var init} ; auxiliary variables + documentation-string + list-of-declarations + {form}* ; body) + + ------------------------------------------------------------ */ + +#define push(v,l) l = CONS(v, l) +#define push_var(v, list) \ + check_symbol(v); \ + if (v->symbol.stype == stp_constant) \ + FEerror("~S is not a variable.", 1, v); \ + push(v, list); + +/* + Handles special declarations, removes declarations from body + */ +@(defun si::process_declarations (body &optional doc) + cl_object documentation = Cnil, declarations = Cnil, form, specials = Cnil; + cl_object decls, vars, v; +@ + /* BEGIN: SEARCH DECLARE */ + for (; !endp(body); body = CDR(body)) { + form = CAR(body); + + if (!Null(doc) && type_of(form) == t_string) { + if (documentation == Cnil) + documentation = form; + else + break; + continue; + } + + if (ATOM(form) || (CAR(form) != Sdeclare)) + break; + + for (decls = CDR(form); !endp(decls); decls = CDR(decls)) { + cl_object sentence = CAR(decls); + if (ATOM(sentence)) + FEerror("Illegal declaration form", 1, form); + push(sentence, declarations); + if (CAR(sentence) == Sspecial) + for (vars = CDR(sentence); !endp(vars); vars = CDR(vars)) { + v = CAR(vars); + check_symbol(v); + push(v,specials); + } + } + } + /* END: SEARCH DECLARE */ + + @(return declarations body documentation specials) +@) + +@(defun si::process_lambda_list (lambda) + cl_object documentation, declarations, specials; + cl_object lambda_list, body, form; + cl_object x, v, key, init, spp; + cl_object reqs = Cnil, opts = Cnil, keys = Cnil, rest = Cnil, auxs = Cnil; + int nreq = 0, nopt = 0, nkey = 0, naux = 0; + cl_object allow_other_keys = Cnil; +@ + bds_check; + if (ATOM(lambda)) + FEerror("No lambda list.", 0); + lambda_list = CAR(lambda); + + declarations = siLprocess_declarations(2, CDR(lambda), Ct); + body = VALUES(1); + documentation = VALUES(2); + specials = VALUES(3); + +REQUIRED: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAoptional) + goto OPTIONAL; + if (v == SArest) + goto REST; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + nreq++; + push_var(v, reqs); + } +OPTIONAL: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + spp = Cnil; + init = Cnil; + if (ATOM(x)) { + if (x == SAoptional || x == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (x == SArest) + goto REST; + if (x == SAkey) + goto KEYWORD; + if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + nopt++; + push_var(v, opts); + push(init, opts); + if (spp != Cnil) { + push_var(spp, opts); + } else { + push(Cnil, opts); + } + } + +REST: + if (endp(lambda_list)) + goto ILLEGAL_LAMBDA; + v = CAR(lambda_list); + push_var(v, rest); + + lambda_list = CDR(lambda_list); + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAoptional || v == SArest || v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + goto ILLEGAL_LAMBDA; + +KEYWORD: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + init = Cnil; + spp = Cnil; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAallow_other_keys) { + if (!Null(allow_other_keys)) + goto ILLEGAL_LAMBDA; + allow_other_keys = Ct; + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (key != SAaux) + goto ILLEGAL_LAMBDA; + goto AUX; + } else if (x == SAoptional || x == SArest || x == SAkey) + goto ILLEGAL_LAMBDA; + else if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + if (CONSP(v)) { + x = v; + key = CAR(x); + if (key->symbol.hpack != keyword_package) + FEerror("~S is not a keyword", 1, key); + if (endp(CDR(x)) || !endp(CDDR(x))) + goto ILLEGAL_LAMBDA; + v = CADR(x); + } else { + check_symbol(v); + key = intern(v->symbol.name, keyword_package); + } + nkey++; + push(key, keys); + push_var(v, keys); + push(init, keys); + if (Null(spp)) { + push(Cnil, keys); + } else { + push_var(spp, keys); + } + } + +AUX: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAoptional || x == SArest || + x == SAkey || x == SAallow_other_keys || + x == SAaux) + goto ILLEGAL_LAMBDA; + v = x; + init = Cnil; + } else if (endp(CDDR(x))) { + v = CAR(x); + init = CADR(x); + } else + goto ILLEGAL_LAMBDA; + naux++; + push_var(v, auxs); + push(init, auxs); + } + +OUTPUT: + @(return CONS(MAKE_FIXNUM(nreq), nreverse(reqs)) + CONS(MAKE_FIXNUM(nopt), nreverse(opts)) + nreverse(rest) + allow_other_keys + CONS(MAKE_FIXNUM(nkey), nreverse(keys)) + nreverse(auxs) + documentation + specials + declarations + body) + +ILLEGAL_LAMBDA: + FEerror("Illegal lambda list ~S.", 1, CAR(lambda)); +@) + +static void +c_default(cl_index deflt_pc) { + cl_object deflt = asm_ref(deflt_pc); + enum cl_type t = type_of(deflt); + if ((t == t_symbol) && (deflt->symbol.stype == stp_constant)) + /* FIXME! Shouldn't this happen only in unsafe mode */ + asm_at(deflt_pc, SYM_VAL(deflt)); + else if ((t == t_symbol) || (t == t_cons) || (t == t_fixnum)) { + cl_index pc = current_pc(); + asm_at(deflt_pc, MAKE_FIXNUM(pc-deflt_pc)); + compile_form(deflt, FALSE); + asm_op(OP_EXIT); + } +} + +static void +c_register_var2(register cl_object var, register cl_object *specials) +{ + if (Null(var)) + return; + if (member_eq(var, *specials)) + c_register_var(var, TRUE); + else if (var->symbol.stype == stp_special) { + *specials = CONS(var, *specials); + c_register_var(var, TRUE); + } else if (var->symbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + c_register_var(var, FALSE); +} + +cl_object +make_lambda(cl_object name, cl_object lambda) { + cl_object reqs, opts, rest, keys, auxs, allow_other_keys; + cl_object specials, doc, decl, body, l; + cl_index specials_pc, opts_pc, keys_pc, label; + int nopts, nkeys; + cl_index handle; + cl_object lex_old = lex_env; + + lex_copy(); + + /* Mark closure boundary */ + CDR(lex_env) = CONS(CONS(Ct, Cnil), CDR(lex_env)); + + reqs = siLprocess_lambda_list(1,lambda); + opts = VALUES(1); + rest = VALUES(2); + allow_other_keys = VALUES(3); + keys = VALUES(4); + auxs = VALUES(5); + doc = VALUES(6); + specials = VALUES(7); + decl = VALUES(8); + body = VALUES(9); + + handle = asm_begin(); + + asm1(name); /* Name of the function */ + specials_pc = current_pc(); /* Which variables are declared special */ + asm1(specials); + + asm_list(reqs); /* Special arguments */ + reqs = CDR(reqs); + while (!endp(reqs)) { + cl_object v = pop(&reqs); + c_register_var2(v, &specials); + } + + opts_pc = current_pc()+1; /* Optional arguments */ + nopts = fix(CAR(opts)); + asm_list(opts); + + asm_list(rest); /* Name of &rest argument */ + + asm1(allow_other_keys); /* Value of &allow-other-keys */ + + keys_pc = current_pc()+1; /* Keyword arguments */ + nkeys = fix(CAR(keys)); + asm_list(keys); + asmn(2, doc, decl); + + label = asm_jmp(OP_JMP); + + while (nopts--) { + c_default(opts_pc+1); + c_register_var2(asm_ref(opts_pc), &specials); + c_register_var2(asm_ref(opts_pc+2), &specials); + opts_pc+=3; + } + c_register_var2(car(rest), &specials); + while (nkeys--) { + c_default(keys_pc+2); + c_register_var2(asm_ref(keys_pc+1), &specials); + c_register_var2(asm_ref(keys_pc+3), &specials); + keys_pc+=4; + } + + if ((current_pc() - label) == 1) + set_pc(label); + else + asm_complete(OP_JMP, label); + while (!endp(auxs)) { /* Local bindings */ + cl_object var = pop(&auxs); + cl_object value = pop(&auxs); + compile_form(value, FALSE); + c_bind(var, specials); + } + asm_at(specials_pc, specials); + compile_body(body); + asm_op(OP_HALT); + + lex_env = lex_old; + + return asm_end(handle); +} + +static cl_object +alloc_bytecodes() +{ + cl_object vector = alloc_simple_vector(128, aet_object); + array_allocself(vector); + vector->vector.hasfillp = TRUE; + vector->vector.fillp = 0; + return vector; +} + +@(defun si::make_lambda (name rest) + cl_object lambda, old_bytecodes = bytecodes; + cl_object lex_old = lex_env; +@ + lex_new(); + bytecodes = alloc_bytecodes(); + lambda = make_lambda(name,rest); + bytecodes = old_bytecodes; + lex_env = lex_old; + @(return lambda) +@) + +cl_object +eval(cl_object form, cl_object *new_bytecodes) +{ + cl_object old_bytecodes = bytecodes; + cl_index handle; + + if (new_bytecodes == NULL) + bytecodes = alloc_bytecodes(); + else if (*new_bytecodes != Cnil) { + bytecodes = *new_bytecodes; + } else { + bytecodes = *new_bytecodes = alloc_bytecodes(); + } + handle = asm_begin(); + compile_form(form, FALSE); + asm_op(OP_EXIT); + asm_op(OP_HALT); +/* Lprint(1,bytecodes); */ + VALUES(0) = Cnil; + NValues = 0; + interpret(&bytecodes->vector.self.t[handle]); + asm_clear(handle); + bytecodes = old_bytecodes; + return VALUES(0); +} + +void +init_compiler(void) +{ + compiler_record *l; + + register_root(&bytecodes); + + for (l = database; l->name[0] != 0; l++) + l->symbol = _intern(l->name, lisp_package); +} diff --git a/src/c/new/interpreter.d b/src/c/new/interpreter.d new file mode 100644 index 000000000..150ae7e50 --- /dev/null +++ b/src/c/new/interpreter.d @@ -0,0 +1,874 @@ +/* + interpreter.c -- Bytecode interpreter. +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +#define next_code(v) *(v++) + +static void +lambda_bind_var(cl_object var, cl_object val, cl_object specials) +{ + if (!member_eq(var, specials)) + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); + else { + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); + } +} + +static void +bind_var(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); +} + +static void +bind_special(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); +} + +static cl_object * +lambda_bind(int narg, cl_object lambda_list, cl_object *args) +{ + cl_object *data = &lambda_list->bytecodes.data[2]; + cl_object specials = lambda_list->bytecodes.data[1]; + cl_object aux; + int i, n; + bool other_keys = FALSE; + bool check_remaining = TRUE; + + /* 1) REQUIRED ARGUMENTS: N var1 ... varN */ + n = fix(next_code(data)); + if (narg < n) + check_arg_failed(narg, n); + for (; n; n--, narg--) + lambda_bind_var(next_code(data), next_code(args), specials); + + /* 2) OPTIONAL ARGUMENTS: N var1 value1 flag1 ... varN valueN flagN */ + for (n = fix(next_code(data)); n; n--, data+=3) { + if (narg) { + lambda_bind_var(data[0], args[0], specials); + args++; narg--; + if (!Null(data[2])) + lambda_bind_var(data[2], Ct, specials); + } else { + cl_object defaults = data[1]; + if (FIXNUMP(defaults)) { + interpret(&data[1] + fix(defaults)); + defaults = VALUES(0); + } + lambda_bind_var(data[0], defaults, specials); + if (!Null(data[2])) + lambda_bind_var(data[2], Cnil, specials); + } + } + + /* 3) REST ARGUMENT: {rest-var | NIL} */ + if (!Null(data[0])) { + cl_object rest = Cnil; + check_remaining = FALSE; + for (i=narg; i; ) + rest = CONS(args[--i], rest); + lambda_bind_var(data[0], rest, specials); + } + data++; + + /* 4) ALLOW-OTHER-KEYS: { T | NIL } */ + other_keys = !Null(next_code(data)); + + /* 5) KEYWORDS: N key1 var1 value1 flag1 ... keyN varN valueN flagN */ + n = fix(next_code(data)); + if (n != 0 || other_keys) { + cl_object *keys; + cl_object spp[n]; + bool other_found = FALSE; + for (i=0; isymbol.hpack != keyword_package) + FEerror("Not a keyword ~S.", 1, args[0]); + keys = data; + for (i = 0; i < n; i++, keys += 4) { + if (args[0] == keys[0]) { + if (spp[i] == OBJNULL) + spp[i] = args[1]; + goto FOUND; + } + } + if (args[0] != SAallow_other_keys) + other_found = TRUE; + else + other_keys = (args[1] == Cnil); + FOUND: + } + if (other_found && !other_keys) + FEerror("Unknown keys found", 0); + for (i=0; ibytecodes.data[0]); + + return &data[2]; +} + +cl_object +lambda_apply(int narg, cl_object fun, cl_object *args) +{ cl_object lex_old = lex_env; + cl_object output, name, *body; + bds_ptr old_bds_top; + volatile bool block, closure; + + if (type_of(fun) != t_bytecodes) + FEinvalid_function(fun); + + /* Set the lexical environment of the function */ + ihs_check; + if (Null(fun->bytecodes.lex)) + lex_env = CONS(Cnil, Cnil); + else + lex_env = CONS(CAR(fun->bytecodes.lex),CDR(fun->bytecodes.lex)); + ihs_push(fun, lex_env); + old_bds_top = bds_top; + + /* Establish bindings */ + body = lambda_bind(narg, fun, args); + + /* If it is a named lambda, set a block for RETURN-FROM */ + block = FALSE; + name = fun->bytecodes.data[0]; + if (Null(fun->bytecodes.data[0])) + block = FALSE; + else { + block = TRUE; + fun = new_frame_id(); + lex_block_bind(name, fun); + if (frs_push(FRS_CATCH, fun)) { + output = VALUES(0); + goto END; + } + } + + /* Process statements */ + VALUES(0) = Cnil; + NValues = 0; + interpret(body); + +END: if (block) frs_pop(); + bds_unwind(old_bds_top); + lex_env = lex_old; + ihs_pop(); + returnn(VALUES(0)); +} + + +/* ----------------- BYTECODE STACK --------------- */ + +cl_object stack = OBJNULL; + +static void +stack_grow(void) { + cl_object *old_data = stack->vector.self.t; + cl_index old_size = stack->vector.fillp; + stack->vector.dim += 128; + array_allocself(stack); + memcpy(stack->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +push1(register cl_object op) { + cl_index where; + where = stack->vector.fillp; + if (where >= stack->vector.dim) + stack_grow(); + stack->vector.self.t[where] = op; + stack->vector.fillp++; +} + +static cl_object +pop1() { + return stack->vector.self.t[--stack->vector.fillp]; +} + +static cl_index +get_sp_index() { + return stack->vector.fillp; +} + +static void +dec_sp_index(register cl_index delta) { + stack->vector.fillp -= delta; +} + +static void +set_sp_index(register cl_index sp) { + if (stack->vector.fillp < sp) + FEerror("Tried to advance stack", 0); + stack->vector.fillp = sp; +} + +static cl_object * +get_sp() { + return stack->vector.self.t + stack->vector.fillp; +} + +static cl_object * +get_sp_at(cl_index where) { + return stack->vector.self.t + where; +} + +/* -------------------- AIDS TO THE INTERPRETER -------------------- */ + +static inline cl_fixnum +get_oparg(cl_object o) { + return GET_OPARG(o); +} + +static inline cl_object * +packed_label(cl_object *v) { + return v + GET_OPARG(v[0]); +} + +static inline cl_object * +simple_label(cl_object *v) { + return v + fix(v[0]); +} + +static cl_object +search_symbol_function(register cl_object fun) { + cl_object output = lex_fun_sch(fun); + if (!Null(output)) + return output; + output = SYM_FUN(fun); + if (output == OBJNULL || fun->symbol.mflag) + FEundefined_function(fun); + return output; +} + +static cl_object +search_symbol_value(register cl_object s) { + cl_object x; + /* x = lex_var_sch(form); */ + for (x = CAR(lex_env); CONSP(x); x = CDR(x)) + if (CAAR(x) == s) { + x = CDAR(x); + if (ENDP(x)) break; + return CAR(x); + } + x = SYM_VAL(s); + if (x == OBJNULL) + FEunbound_variable(s); + return x; +} + +static cl_object +interpret_apply(int narg, cl_object fun, cl_object *args) { + cl_object x; + + AGAIN: + switch (type_of(fun)) { + case t_cfun: + ihs_push_funcall(fun->cfun.name); + x = APPLY(narg, fun->cfun.entry, args); + ihs_pop(); + return x; + case t_cclosure: + /* FIXME! Shouldn't we register this call somehow? */ + return APPLY_closure(narg, fun->cclosure.entry, fun->cclosure.env, args); +#ifdef CLOS + case t_gfun: + ihs_push_funcall(fun->gfun.name); + x = gcall(narg, fun, args); + ihs_pop(); + return x; +#endif + case t_bytecodes: + return lambda_apply(narg, fun, args); + case t_symbol: + fun = search_symbol_function(fun); + goto AGAIN; + default: + } + FEinvalid_function(fun); +} + +/* -------------------- THE INTERPRETER -------------------- */ + +static cl_object * +interpret_block(cl_object *vector) { + cl_object * volatile exit, name; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + lex_copy(); + + exit = packed_label(vector - 1); + lex_block_bind(next_code(vector), id); + if (frs_push(FRS_CATCH,id) == 0) + vector = interpret(vector); + frs_pop(); + lex_env = lex_old; + return exit; +} + +static cl_object * +interpret_catch(cl_object *vector) { + cl_object * volatile exit; + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,VALUES(0)) == 0) + interpret(vector); + frs_pop(); + return exit; +} + +static cl_object * +interpret_tagbody(cl_object *vector) { + cl_index i, ntags = fix(get_oparg(vector[-1])); + cl_object lex_old = lex_env; + cl_object id = new_frame_id(); + cl_object *aux, *tag_list = vector; + + lex_copy(); + aux = vector; + for (i=0; i= ntags) + FEerror("Someone tried to RETURN-FROM a TAGBODY",0); + else + aux = simple_label(aux); + } + vector = interpret(aux); + frs_pop(); + lex_env = lex_old; + VALUES(0) = Cnil; + NValues = 0; + return vector; +} + +static cl_object * +interpret_unwind_protect(cl_object *vector) { + bool unwinding; + int nr; + cl_object * volatile exit; + + exit = packed_label(vector-1); + if (frs_push(FRS_PROTECT, Cnil)) + unwinding = TRUE; + else { + interpret(vector); + unwinding = FALSE; + } + nr = NValues; + MV_SAVE(nr); + exit = interpret(exit); + MV_RESTORE(nr); + frs_pop(); + if (unwinding) + unwind(nlj_fr, nlj_tag); + return exit; +} + +static cl_object * +interpret_do(cl_object *vector) { + cl_object *volatile exit; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + exit = packed_label(vector-1); + if (frs_push(FRS_CATCH,id) == 0) + interpret(vector); + frs_pop(); + + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dolist(cl_object *vector) { + cl_object *output, *volatile exit; + cl_object list, var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + list = VALUES(0); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Build list & bind variable*/ + vector = interpret(vector); + output = packed_label(vector-1); + while (!endp(list)) { + NValues = 1; + VALUES(0) = CAR(list); + interpret(vector); + list = CDR(list); + } + VALUES(0) = Cnil; + NValues = 1; + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dotimes(cl_object *vector) { + cl_object *output, *volatile exit; + cl_fixnum length, i; + cl_object var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + length = fix(VALUES(0)); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Bind variable */ + vector = interpret(vector); + output = packed_label(vector-1); + for (i = 0; i < length;) { + interpret(vector); + NValues = 1; + VALUES(0) = MAKE_FIXNUM(++i); + } + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object +close_around(cl_object fun, cl_object lex) { + cl_object v = alloc_object(t_bytecodes); + v->bytecodes.size = fun->bytecodes.size; + v->bytecodes.data = fun->bytecodes.data; + if (!Null(CAR(lex)) || !Null(CDR(lex))) + v->bytecodes.lex = CONS(CAR(lex),CDR(lex)); + else + v->bytecodes.lex = Cnil; + return v; +} + +static cl_object * +interpret_flet(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index nfun = get_oparg(vector[-1]); + + lex_copy(); + while (nfun--) { + cl_object fun = next_code(vector); + cl_object f = close_around(fun,lex_old); + lex_fun_bind(f->bytecodes.data[0], f); + } + vector = interpret(vector); + lex_env = lex_old; + return vector; +} + +static cl_object * +interpret_labels(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index i, nfun = get_oparg(vector[-1]); + cl_object l; + + lex_copy(); + for (i=0; ibytecodes.data[0], f); + } + /* Update the closures so that all functions can call each other */ + for (i=0, l=CDR(lex_env); isymbol.stype == stp_constant) + FEerror("Cannot set the constant ~A", 1, var); + else + SYM_VAL(var) = value; + } + } + if (NValues > 1) NValues = 1; + return vector; +} + +static cl_object * +interpret_progv(cl_object *vector) { + cl_object values = VALUES(0); + cl_object vars = pop1(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + while (!endp(vars)) { + if (values == Cnil) + bds_bind(CAR(vars), OBJNULL); + else { + bds_bind(CAR(vars), car(values)); + values = CDR(values); + } + vars = CDR(vars); + } + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +static cl_object * +interpret_pushenv(cl_object *vector) { + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +cl_object * +interpret(cl_object *vector) { + enum cl_type t; + cl_object s; + cl_fixnum n; + + BEGIN: + s = next_code(vector); + t = type_of(s); + if (t == t_symbol) { + VALUES(0) = search_symbol_value(s); + NValues = 1; + goto BEGIN; + } + if (t != t_fixnum) { + VALUES(0) = s; + NValues = 1; + goto BEGIN; + } + switch (GET_OP(s)) { + case OP_PUSHQ: + push1(next_code(vector)); + break; + case OP_PUSH: + push1(VALUES(0)); + break; + case OP_PUSHV: + push1(search_symbol_value(next_code(vector))); + break; + case OP_QUOTE: + VALUES(0) = next_code(vector); + NValues = 1; + break; + case OP_NOP: + VALUES(0) = Cnil; + NValues = 0; + break; + case OP_BLOCK: + vector = interpret_block(vector); + break; + case OP_PUSHVALUES: { + int i; + for (i=0; isymbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + SYM_VAL(var) = VALUES(0); + break; + } + case OP_PBIND: + bind_var(next_code(vector), pop1()); + break; + case OP_PBINDS: + bind_special(next_code(vector), pop1()); + break; + case OP_PSETQ: + CADR(lex_var_sch(next_code(vector))) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + case OP_PSETQS: { + cl_object var = next_code(vector); + if (var->symbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + SYM_VAL(var) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + } + case OP_MSETQ: + vector = interpret_msetq(vector); + break; + case OP_MBIND: + vector = interpret_mbind(vector); + break; + case OP_MPROG1: + vector = interpret_mprog1(vector); + break; + case OP_PROGV: + vector = interpret_progv(vector); + break; + case OP_PUSHENV: + vector = interpret_pushenv(vector); + break; + case OP_VALUES: { + cl_fixnum n = get_oparg(s); + NValues = n; + while (n) + VALUES(--n) = pop1(); + break; + } + case OP_NTHVAL: { + cl_index n = fix(pop1()); + if (n < 0 || n >= NValues) + VALUES(0) = Cnil; + else + VALUES(0) = VALUES(n); + NValues = 1; + break; + } + case OP_DOLIST: + vector = interpret_dolist(vector); + break; + case OP_DOTIMES: + vector = interpret_dotimes(vector); + break; + case OP_DO: + vector = interpret_do(vector); + break; + case OP_TAGBODY: + vector = interpret_tagbody(vector); + break; + case OP_UNWIND: + vector = interpret_unwind_protect(vector); + break; + default: + FEerror("Unknown code ~S", 1, MAKE_FIXNUM(*(vector-1))); + } + goto BEGIN; +} + +@(defun si::interpreter_stack () +@ + @(return stack) +@) + +void +init_interpreter(void) +{ + register_root(&stack); + stack = alloc_simple_vector(128, aet_object); + array_allocself(stack); + stack->vector.hasfillp = TRUE; + stack->vector.fillp = 0; +} diff --git a/src/c/num_arith.d b/src/c/num_arith.d new file mode 100644 index 000000000..e12f93f23 --- /dev/null +++ b/src/c/num_arith.d @@ -0,0 +1,908 @@ +/* + num_arith.c -- Arithmetic operations +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + + +/* (* ) */ + +@(defun times (&rest nums) + int i; + cl_object numi, prod = MAKE_FIXNUM(1); +@ + /* INV: type check in number_times() */ + for (i = 0; i < narg; i++) { + numi = va_arg(nums, cl_object); + prod = number_times(prod, numi); + } + @(return prod) +@) + +cl_object +fixnum_times(int i, int j) +{ + + int high, sign; + mp_limb_t i0, j0, res[2]; + cl_object z; + + if (i == 0 || j == 0) + return(MAKE_FIXNUM(0)); + i0 = abs(i); + j0 = abs(j); + sign = ((i >= 0 && j >= 0) || (i < 0 && j < 0)) ? 1 : -1; + high = mpn_mul(res, &i0, 1, &j0, 1); + if (high == 0) { + if (sign > 0) { + if (res[0] <= MOST_POSITIVE_FIX) + return(MAKE_FIXNUM(res[0])); + } else { + if (res[0] <= (MOST_POSITIVE_FIX + 1)) + return(MAKE_FIXNUM(-res[0])); + } + z = alloc_object(t_bignum); + mpz_init_set_si(z->big.big_num, sign * res[0]); + } else { + z = bignum2(res[1], res[0]); + z->big.big_size = sign * 2; + } + return(z); +} + +static cl_object +big_times_fix(cl_object b, int i) +{ + cl_object z; + + if (i == 1) + return(b); + if (i == -1) + return(big_minus(b)); + z = big_register0_get(); + mpz_mul_ui(z->big.big_num, b->big.big_num, abs(i)); + if (i < 0) + big_complement(z); + z = big_register_normalize(z); + return(z); +} + +static cl_object +big_times_big(cl_object x, cl_object y) +{ + cl_object z; + z = big_register0_get(); + mpz_mul(z->big.big_num, x->big.big_num, y->big.big_num); + z = big_register_normalize(z); + return(z); +} + +cl_object +number_times(cl_object x, cl_object y) +{ + cl_object z, z1; + + switch (type_of(x)) { + case t_fixnum: + switch (type_of(y)) { + case t_fixnum: + return fixnum_times(fix(x),fix(y)); + case t_bignum: + return big_times_fix(y, fix(x)); + case t_ratio: + z = number_times(x, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(fix(x) * sf(y)); + case t_longfloat: + return make_longfloat(fix(x) * lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + return big_times_fix(x, fix(y)); + case t_bignum: + return big_times_big(x, y); + case t_ratio: + z = number_times(x, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) * sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) * lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + z = number_times(x->ratio.num, y); + z = make_ratio(z, x->ratio.den); + return(z); + case t_ratio: + z = number_times(x->ratio.num,y->ratio.num); + z1 = number_times(x->ratio.den,y->ratio.den); + z = make_ratio(z, z1); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) * sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) * lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_shortfloat: + switch (type_of(y)) { + case t_fixnum: + return make_shortfloat(fix(y) * sf(x)); + case t_bignum: + case t_ratio: + return make_shortfloat(number_to_double(y) * sf(x)); + case t_shortfloat: + return make_shortfloat(sf(y) * sf(x)); + case t_longfloat: + return make_longfloat(lf(y) * sf(x)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_longfloat: + switch (type_of(y)) { + case t_fixnum: + return make_longfloat(fix(y) * lf(x)); + case t_bignum: + case t_ratio: + return make_longfloat(number_to_double(y) * lf(x)); + case t_shortfloat: + return make_longfloat(sf(y) * lf(x)); + case t_longfloat: + return make_longfloat(lf(y) * lf(x)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_complex: + { + cl_object z11, z12, z21, z22; + + if (type_of(y) != t_complex) { + cl_object aux = x; + x = y; y = aux; + COMPLEX: /* INV: x is real, y is complex */ + return make_complex(number_times(x, y->complex.real), + number_times(x, y->complex.imag)); + } + z11 = number_times(x->complex.real, y->complex.real); + z12 = number_times(x->complex.imag, y->complex.imag); + z21 = number_times(x->complex.imag, y->complex.real); + z22 = number_times(x->complex.real, y->complex.imag); + return(make_complex(number_minus(z11, z12), number_plus(z21, z22))); + } + default: + FEtype_error_number(x); + } +} + + /* (+ ) */ +@(defun plus (&rest nums) + int i; + cl_object numi, sum = MAKE_FIXNUM(0); +@ + /* INV: type check is in number_plus() */ + for (i = 0; i < narg; i++) { + numi = va_arg(nums, cl_object); + sum = number_plus(sum, numi); + } + @(return sum) +@) + +cl_object +number_plus(cl_object x, cl_object y) +{ + int i, j; + cl_object z, z1; + + switch (type_of(x)) { + case t_fixnum: + switch (type_of(y)) { + case t_fixnum: { + int k = fix(x) + fix(y); + if (k >= MOST_NEGATIVE_FIX && k <= MOST_POSITIVE_FIX) + return(MAKE_FIXNUM(k)); + else + return(bignum1(k)); + } + case t_bignum: + if ((i = fix(x)) == 0) + return(y); + z = big_register0_get(); + if (i > 0) + mpz_add_ui(z->big.big_num, y->big.big_num, i); + else + mpz_sub_ui(z->big.big_num, y->big.big_num, -i); + z = big_register_normalize(z); + return(z); + case t_ratio: + z = number_times(x, y->ratio.den); + z = number_plus(z, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(fix(x) + sf(y)); + case t_longfloat: + return make_longfloat(fix(x) + lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + if ((j = fix(y)) == 0) + return(x); + z = big_register0_get(); + if (j > 0) + mpz_add_ui(z->big.big_num, x->big.big_num, j); + else + mpz_sub_ui(z->big.big_num, x->big.big_num, -j); + z = big_register_normalize(z); + return(z); + case t_bignum: + z = big_plus(x, y); + z = big_normalize(z); + return(z); + case t_ratio: + z = number_times(x, y->ratio.den); + z = number_plus(z, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) + sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) + lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + z = number_times(x->ratio.den, y); + z = number_plus(x->ratio.num, z); + z = make_ratio(z, x->ratio.den); + return(z); + case t_ratio: + z1 = number_times(x->ratio.num,y->ratio.den); + z = number_times(x->ratio.den,y->ratio.num); + z = number_plus(z1, z); + z1 = number_times(x->ratio.den,y->ratio.den); + z = make_ratio(z, z1); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) + sf(y)); + case t_longfloat: + return make_shortfloat(number_to_double(x) + lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_shortfloat: + switch (type_of(y)) { + case t_fixnum: + return make_shortfloat(fix(y) + sf(x)); + case t_bignum: + case t_ratio: + return make_shortfloat(number_to_double(y) + sf(x)); + case t_shortfloat: + return make_shortfloat(sf(y) + sf(x)); + case t_longfloat: + return make_longfloat(lf(y) + sf(x)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_longfloat: + switch (type_of(y)) { + case t_fixnum: + return make_longfloat(fix(y) + lf(x)); + case t_bignum: + case t_ratio: + return make_longfloat(number_to_double(y) + lf(x)); + case t_shortfloat: + return make_longfloat(sf(y) + lf(x)); + case t_longfloat: + return make_longfloat(lf(y) + lf(x)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_complex: + if (type_of(y) != t_complex) { + cl_object aux = x; + x = y; y = aux; + COMPLEX: /* INV: x is real, y is complex */ + return make_complex(number_plus(x, y->complex.real), y->complex.imag); + } + z = number_plus(x->complex.real, y->complex.real); + z1 = number_plus(x->complex.imag, y->complex.imag); + z = make_complex(z, z1); + return(z); + default: + FEtype_error_number(x); + } +} + +/* (- ) */ +@(defun minus (num &rest nums) + int i; + cl_object diff; +@ + /* INV: argument type check in number_{negate,minus}() */ + if (narg == 1) + @(return number_negate(num)) + for (i = 1, diff = num; i < narg; i++) { + num = va_arg(nums, cl_object); + diff = number_minus(diff, num); + } + @(return diff) +@) + +cl_object +number_minus(cl_object x, cl_object y) +{ + int i, j, k; + cl_object z, z1; + + switch (type_of(x)) { + case t_fixnum: + switch(type_of(y)) { + case t_fixnum: + if ((k = fix(x) - fix(y)) >= MOST_NEGATIVE_FIX && + k <= MOST_POSITIVE_FIX) + return(MAKE_FIXNUM(k)); + else + return(bignum1(k)); + case t_bignum: + z = big_register0_get(); + i = fix(x); + if (i > 0) + mpz_sub_ui(z->big.big_num, y->big.big_num, i); + else + mpz_add_ui(z->big.big_num, y->big.big_num, -i); + big_complement(z); + z = big_register_normalize(z); + return(z); + case t_ratio: + z = number_times(x, y->ratio.den); + z = number_minus(z, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(fix(x) - sf(y)); + case t_longfloat: + return make_shortfloat(fix(x) - lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + if ((j = fix(y)) == 0) + return(x); + z = big_register0_get(); + if (j > 0) + mpz_sub_ui(z->big.big_num, x->big.big_num, j); + else + mpz_add_ui(z->big.big_num, x->big.big_num, -j); + z = big_register_normalize(z); + return(z); + case t_bignum: + y = big_minus(y); + z = big_plus(x, y); + z = big_normalize(z); + return(z); + case t_ratio: + z = number_times(x, y->ratio.den); + z = number_minus(z, y->ratio.num); + z = make_ratio(z, y->ratio.den); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) - sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) - lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + z = number_times(x->ratio.den, y); + z = number_minus(x->ratio.num, z); + z = make_ratio(z, x->ratio.den); + return(z); + case t_ratio: + z = number_times(x->ratio.num,y->ratio.den); + z1 = number_times(x->ratio.den,y->ratio.num); + z = number_minus(z, z1); + z1 = number_times(x->ratio.den,y->ratio.den); + z = make_ratio(z, z1); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) - sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) - lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_shortfloat: + switch (type_of(y)) { + case t_fixnum: + return make_shortfloat(sf(x) - fix(y)); + case t_bignum: + case t_ratio: + return make_shortfloat(sf(x) - number_to_double(y)); + case t_shortfloat: + return make_shortfloat(sf(x) - sf(y)); + case t_longfloat: + return make_longfloat(sf(x) - lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_longfloat: + switch (type_of(y)) { + case t_fixnum: + return make_longfloat(lf(x) - fix(y)); + case t_bignum: + case t_ratio: + return make_longfloat(lf(x) - number_to_double(y)); + case t_shortfloat: + return make_longfloat(lf(x) - sf(y)); + case t_longfloat: + return make_longfloat(lf(x) - lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + COMPLEX: + return make_complex(number_minus(x, y->complex.real), + number_negate(y->complex.imag)); + case t_complex: + if (type_of(y) != t_complex) { + z = number_minus(x->complex.real, y); + z1 = x->complex.imag; + } else { + z = number_minus(x->complex.real, y->complex.real); + z1 = number_minus(x->complex.imag, y->complex.imag); + } + return make_complex(z, z1); + default: + FEtype_error_number(x); + } +} + +@(defun conjugate (c) +@ + switch (type_of(c)) { + case t_complex: + c = make_complex(c->complex.real, + number_negate(c->complex.imag)); + case t_fixnum: + case t_bignum: + case t_ratio: + case t_shortfloat: + case t_longfloat: + break; + default: + FEtype_error_number(c); + } + @(return c) +@) + +cl_object +number_negate(cl_object x) +{ + cl_object z, z1; + + switch (type_of(x)) { + case t_fixnum: { + int k = fix(x); + /* -MOST_NEGATIVE_FIX > MOST_POSITIVE_FIX */ + if (k == MOST_NEGATIVE_FIX) + return(bignum1(- MOST_NEGATIVE_FIX)); + else + return(MAKE_FIXNUM(-k)); + } + case t_bignum: + z = big_register0_get(); + mpz_neg(z->big.big_num, x->big.big_num); + return(big_register_copy(z)); + + case t_ratio: + z1 = number_negate(x->ratio.num); + z = alloc_object(t_ratio); + z->ratio.num = z1; + z->ratio.den = x->ratio.den; + return(z); + + case t_shortfloat: + z = alloc_object(t_shortfloat); + sf(z) = -sf(x); + return(z); + + case t_longfloat: + z = alloc_object(t_longfloat); + lf(z) = -lf(x); + return(z); + + case t_complex: + z = number_negate(x->complex.real); + z1 = number_negate(x->complex.imag); + z = make_complex(z, z1); + return(z); + + default: + FEtype_error_number(x); + } +} + +/* (/ ) */ +@(defun divide (num &rest nums) + int i; +@ + /* INV: type check is in number_divide() */ + if (narg == 0) + FEtoo_few_arguments(&narg); + if (narg == 1) + @(return number_divide(MAKE_FIXNUM(1), num)) + for (i = 1; i < narg; i++) + num = number_divide(num, va_arg(nums, cl_object)); + @(return num) +@) + +cl_object +number_divide(cl_object x, cl_object y) +{ + cl_object z, z1, z2, z3; + + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + if (number_minusp(y) == TRUE) { + x = number_negate(x); + y = number_negate(y); + } + z = make_ratio(x, y); + return(z); + case t_ratio: + z = number_times(x, y->ratio.den); + z = make_ratio(z, y->ratio.num); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) / sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) / lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + z = number_times(x->ratio.den, y); + z = make_ratio(x->ratio.num, z); + return(z); + case t_ratio: + z = number_times(x->ratio.num,y->ratio.den); + z1 = number_times(x->ratio.den,y->ratio.num); + z = make_ratio(z, z1); + return(z); + case t_shortfloat: + return make_shortfloat(number_to_double(x) / sf(y)); + case t_longfloat: + return make_longfloat(number_to_double(x) / lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_shortfloat: + switch (type_of(y)) { + case t_fixnum: + return make_shortfloat(sf(x) / fix(y)); + case t_bignum: + case t_ratio: + return make_shortfloat(sf(x) / number_to_double(y)); + case t_shortfloat: + return make_shortfloat(sf(x) / sf(y)); + case t_longfloat: + return make_longfloat(sf(x) / lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_longfloat: + switch (type_of(y)) { + case t_fixnum: + return make_longfloat(lf(x) / fix(y)); + case t_bignum: + case t_ratio: + return make_longfloat(lf(x) / number_to_double(y)); + case t_shortfloat: + return make_longfloat(lf(x) / sf(y)); + case t_longfloat: + return make_longfloat(lf(x) / lf(y)); + case t_complex: + goto COMPLEX; + default: + FEtype_error_number(y); + } + case t_complex: + if (type_of(y) != t_complex) { + z1 = number_divide(x->complex.real, y); + z2 = number_divide(x->complex.imag, y); + return make_complex(z1, z2); + } else if (1) { + /* #C(z1 z2) = #C(xr xi) * #C(yr -yi) */ + z1 = number_plus(number_times(x->complex.real, y->complex.real), + number_times(x->complex.imag, y->complex.imag)); + z2 = number_minus(number_times(x->complex.imag, y->complex.real), + number_times(x->complex.real, y->complex.imag)); + } else { + COMPLEX: /* INV: x is real, y is complex */ + /* #C(z1 z2) = x * #C(yr -yi) */ + z1 = number_times(x, y->complex.real); + z2 = number_negate(number_times(x, y->complex.imag)); + } + z = number_plus(number_times(y->complex.real, y->complex.real), + number_times(y->complex.imag, y->complex.imag)); + z = make_complex(number_divide(z1, z), number_divide(z2, z)); + return(z); + default: + FEtype_error_number(x); + } +} + +cl_object +integer_divide(cl_object x, cl_object y) +{ + enum type tx, ty; + + tx = type_of(x); + ty = type_of(y); + if (tx == t_fixnum) { + if (ty == t_fixnum) + return MAKE_FIXNUM(fix(x) / fix(y)); + if (ty == t_bignum) + return MAKE_FIXNUM(0); + FEtype_error_integer(y); + } + if (tx == t_bignum) { + cl_object q = big_register0_get(); + if (ty == t_bignum) { + mpz_tdiv_q(q->big.big_num, x->big.big_num, y->big.big_num); + } else if (ty == t_fixnum) { + cl_fixnum j = fix(y); + mpz_tdiv_q_ui(q->big.big_num, x->big.big_num, abs(j)); + if (j < 0) + mpz_neg(q->big.big_num, q->big.big_num); + } else { + FEtype_error_integer(y); + } + return big_register_normalize(q); + } + FEtype_error_integer(x); +} + +@(defun gcd (&rest nums) + int i; + cl_object gcd; +@ + if (narg == 0) + @(return MAKE_FIXNUM(0)) + /* INV: get_gcd() checks types */ + gcd = va_arg(nums, cl_object); + if (narg == 1) + @(return (number_minusp(gcd) ? number_negate(gcd) : gcd)) + for (i = 1; i < narg; i++) + gcd = get_gcd(gcd, va_arg(nums, cl_object)); + @(return gcd) +@) + +cl_object +get_gcd(cl_object x, cl_object y) +{ + enum cl_type tx = type_of(x); + enum cl_type ty = type_of(y); + cl_object gcd; + + switch (tx) { + case t_fixnum: + if (ty == t_fixnum) { + cl_fixnum i = fix(x); + cl_fixnum j = fix(y); + for (i = abs(i), j = abs(j); TRUE; ) { + cl_fixnum k; + if (i < j) { + k = i; + i = j; + j = k; + } + if (j == 0) + return(MAKE_FIXNUM(i)); + k = i % j; + i = j; + j = k; + } + } else { + x = bignum1(fix(x)); + } + break; + case t_bignum: + break; + default: + FEtype_error_integer(x); + } + switch (ty) { + case t_fixnum: + y = bignum1(fix(y)); + case t_bignum: + gcd = big_register0_get(); + mpz_gcd(gcd->big.big_num, x->big.big_num, y->big.big_num); + gcd = big_register_normalize(gcd); + return(gcd); + default: + FEtype_error_integer(y); + } +} + +/* (1+ x) */ +@(defun one_plus (x) +@ /* INV: type check is in one_plus() */ + @(return one_plus(x)) +@) + + +cl_object +one_plus(cl_object x) +{ + cl_object z; + + switch (type_of(x)) { + + case t_fixnum: + if (x == MAKE_FIXNUM(MOST_POSITIVE_FIX)) + return(bignum1(MOST_POSITIVE_FIX+1)); + return (cl_object)((int)x + ((int)MAKE_FIXNUM(1) - FIXNUM_TAG)); + case t_bignum: + return(number_plus(x, MAKE_FIXNUM(1))); + + case t_ratio: + z = number_plus(x->ratio.num, x->ratio.den); + z = make_ratio(z, x->ratio.den); + return(z); + + case t_shortfloat: + z = alloc_object(t_shortfloat); + sf(z) = sf(x) + 1.0; + return(z); + + case t_longfloat: + z = alloc_object(t_longfloat); + lf(z) = lf(x) + 1.0; + return(z); + + case t_complex: + z = one_plus(x->complex.real); + z = make_complex(z, x->complex.imag); + return(z); + + default: + FEtype_error_number(x); + } +} + +/* (1- x) */ +@(defun one_minus (x) +@ /* INV: type check is in one_minus() */ + @(return one_minus(x)) +@) + + +cl_object +one_minus(cl_object x) +{ + cl_object z; + + switch (type_of(x)) { + + case t_fixnum: + if (x == MAKE_FIXNUM(MOST_NEGATIVE_FIX)) + return(bignum1(MOST_NEGATIVE_FIX-1)); + return (cl_object)((int)x - ((int)MAKE_FIXNUM(1) - FIXNUM_TAG)); + + case t_bignum: + return(number_minus(x, MAKE_FIXNUM(1))); + + case t_ratio: + z = number_minus(x->ratio.num, x->ratio.den); + z = make_ratio(z, x->ratio.den); + return(z); + + case t_shortfloat: + z = alloc_object(t_shortfloat); + sf(z) = sf(x) - 1.0; + return(z); + + case t_longfloat: + z = alloc_object(t_longfloat); + lf(z) = lf(x) - 1.0; + return(z); + + case t_complex: + z = one_minus(x->complex.real); + z = make_complex(z, x->complex.imag); + return(z); + + default: + FEtype_error_real(x); + } +} + +@(defun lcm (lcm &rest nums) +@ + /* INV: get_gcd() checks types. By placing `numi' before `lcm' in + this call, we make sure that errors point to `numi' */ + while (narg-- > 1) { + cl_object numi = va_arg(nums, cl_object); + cl_object t = number_times(lcm, numi); + cl_object g = get_gcd(numi, lcm); + lcm = number_divide(t, g); + } + @(return (number_minusp(lcm) ? number_negate(lcm) : lcm)) +@) diff --git a/src/c/num_co.d b/src/c/num_co.d new file mode 100644 index 000000000..996a9c469 --- /dev/null +++ b/src/c/num_co.d @@ -0,0 +1,1171 @@ +/* + num_co.c -- Operations on floating-point numbers. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +/* + IMPLEMENTATION-DEPENDENT + + This file contains those functions + that know the representation of floating-point numbers. +*/ + +#include "ecls.h" +#include +#ifndef HAVE_ISOC99 +# define floorf floor +# define ceilf ceil +# define fabsf fabs +#endif + +static cl_object plus_half, minus_half; + + +#ifdef VAX +/* + radix = 2 + + SEEEEEEEEHHHHHHH The redundant most significant fraction bit + HHHHHHHHHHHHHHHH is not expressed. + LLLLLLLLLLLLLLLL + LLLLLLLLLLLLLLLL +*/ +#endif +#ifdef IEEEFLOAT +# ifndef WORDS_BIGENDIAN +/* + radix = 2 + + LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL The redundant most + SEEEEEEEEEEEHHHHHHHHHHHHHHHHHHHH significant fraction bit + is not expressed. +*/ +# else +/* + radix = 2 + + SEEEEEEEEEEEHHHHHHHHHHHHHHHHHHHH The redundant most + LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL significant fraction bit + is not expressed. +*/ +# endif +#endif +#ifdef TAHOE +/* + radix = 2 + + SEEEEEEEEHHHHHHHHHHHHHHHHHHHHHHH The redundant most significant + LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL fraction bit is not expressed. + +*/ +#endif + +static void +integer_decode_double(double d, unsigned *hp, unsigned *lp, int *ep, int *sp) +{ + unsigned h, l; + + if (d == 0.0) { + *hp = *lp = 0; + *ep = 0; + *sp = 1; + return; + } + h = *((unsigned *)&d + HIND); + l = *((unsigned *)&d + LIND); +#ifdef VAX + *ep = ((h >> 7) & 0xff) - 128 - 56; + h = ((h >> 15) & 0x1fffe) | (((h & 0x7f) | 0x80) << 17); + l = ((l >> 16) & 0xffff) | (l << 16); +#endif VAX +#ifdef IEEEFLOAT + *ep = ((h & 0x7ff00000) >> 20) - 1022 - 53; + h = (h & 0x000fffff) | 0x00100000; +#endif IEEEFLOAT +#ifdef TAHOE + *ep = ((h & 0x7f800000) >> 23) - 128 - 56; + h = (h & 0x007fffff) | 0x00800000; +#endif + *hp = h; + *lp = l; + *sp = (d > 0.0 ? 1 : -1); +} + +#ifdef VAX +/* + radix = 2 + + SEEEEEEEEMMMMMMM The redundant most significant fraction bit + MMMMMMMMMMMMMMMM is not expressed. +*/ +#endif VAX +#ifdef IEEEFLOAT +/* + radix = 2 + + SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM The redundant most + significant fraction bit + is not expressed. +*/ +#endif IEEEFLOAT +#ifdef TAHOE +/* + radix = 2 + + SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM The redundant most significant + fraction bit is not expressed. +*/ +#endif +static void +integer_decode_float(double d, int *mp, int *ep, int *sp) +{ + float f; + int m; + + f = d; + if (f == 0.0) { + *mp = 0; + *ep = 0; + *sp = 1; + return; + } + m = *(int *)(&f); +#ifdef VAX + *ep = ((m >> 7) & 0xff) - 128 - 24; + *mp = ((m >> 16) & 0xffff) | (((m & 0x7f) | 0x80) << 16); +#endif VAX +#ifdef IEEEFLOAT + *ep = ((m & 0x7f800000) >> 23) - 126 - 24; + *mp = (m & 0x007fffff) | 0x00800000; +#endif IEEEFLOAT +#ifdef TAHOE + *ep = ((m & 0x7f800000) >> 23) - 128 -24; + *mp = (m & 0x007fffff) | 0x00800000; +#endif + *sp = (f > 0.0 ? 1 : -1); +} + +static int +double_exponent(double value) +{ + int *d = (int*)&value; + if (value == 0.0) + return(0); +#ifdef VAX + return(((d[0] >> 7) & 0xff) - 128); +#endif VAX +#ifdef IEEEFLOAT + return(((d[HIND] & 0x7ff00000) >> 20) - 1022); +#endif IEEEFLOAT +#ifdef TAHOE + return(((d[0] & 0x7f800000) >> 23) - 128); +#endif +} + +static void +set_exponent(double *value, int e) +{ + unsigned int *d = (int*)value; + if (*value == 0.0) + return; +#ifdef VAX + d[0] = (d[0] & 0xffff807f) | (((e + 128) << 7) & 0x7f80); +#endif VAX +#ifdef IEEEFLOAT + d[HIND] = (d[HIND] & 0x800fffff) | (((e + 1022) << 20) & 0x7ff00000); +#endif IEEEFLOAT +#ifdef TAHOE + d[0] = (d[0] & 0x807fffff) | (((e + 128) << 23) & 0x7f800000); +#endif +} + + +cl_object +double_to_integer(double d) +{ + int h, l, e, s; + cl_object x; + + if (d == 0.0) + return(MAKE_FIXNUM(0)); + integer_decode_double(d, &h, &l, &e, &s); + +#if defined(VAX) || defined(TAHOE) + if (e <= -32) { + h >>= (-e) - 32; + return(MAKE_FIXNUM(s*h)); + } +#endif +#ifdef IEEEFLOAT + if (e <= -32) { + e = (-e) - 32; + if (e >= 32) + return(MAKE_FIXNUM(0)); + h >>= e; + return(MAKE_FIXNUM(s*h)); + } +#endif IEEEFLOAT + if (h != 0) + x = bignum2(h, l); + else + x = MAKE_FIXNUM(l); + + x = integer_shift(x, e); + if (s < 0) + x = number_negate(x); + return(x); +} + +static cl_object +number_remainder(cl_object x, cl_object y, cl_object q) +{ + cl_object z; + + z = number_times(q, y); + z = number_minus(x, z); + return(z); +} + +/* Coerce X to single-float if one arg, + otherwise coerce to same float type as second arg */ + +@(defun float (x &optional (y OBJNULL)) + enum type t = t_shortfloat; +@ + if (y != OBJNULL) { + t = type_of(y); + if (t != t_shortfloat && t != t_longfloat) + FEtype_error_float(y); + } + switch (type_of(x)) { + case t_fixnum: + if (t == t_shortfloat) + x = make_shortfloat(fix(x)); + else + x = make_longfloat(fix(x)); + break; + case t_bignum: + case t_ratio: { + double d = number_to_double(x); + if (t == t_shortfloat) + x = make_shortfloat(d); + else + x = make_longfloat(d); + break; + } + case t_shortfloat: + if (t == t_longfloat) + x = make_longfloat(sf(x)); + break; + case t_longfloat: + if (t == t_shortfloat) + x = make_shortfloat(lf(x)); + break; + default: + FEtype_error_real(x); + } + @(return x) +@) + +@(defun numerator (x) + cl_object out; +@ + switch (type_of(x)) { + case t_ratio: + out = x->ratio.num; + break; + case t_fixnum: + case t_bignum: + out = x; + break; + default: + FEwrong_type_argument(Srational, x); + } + @(return out) +@) + +@(defun denominator (x) + cl_object out; +@ + switch (type_of(x)) { + case t_ratio: + out = x->ratio.den; + break; + case t_fixnum: + case t_bignum: + out = MAKE_FIXNUM(1); + break; + default: + FEwrong_type_argument(Srational, x); + } + @(return out) +@) + +cl_object +floor1(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + VALUES(0) = x; + VALUES(1) = MAKE_FIXNUM(0); + break; + case t_ratio: + VALUES(0) = floor2(x->ratio.num, x->ratio.den); + VALUES(1) = make_ratio(VALUES(1), x->ratio.den); + break; + case t_shortfloat: { + float d = sf(x); + float y = floorf(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_shortfloat(d - y); + break; + } + case t_longfloat: { + double d = lf(x); + double y = floor(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_longfloat(d - y); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +cl_object +floor2(cl_object x, cl_object y) +{ + switch(type_of(x)) { + case t_fixnum: + switch(type_of(y)) { + case t_fixnum: { /* FIX / FIX */ + cl_fixnum a = fix(x), b = fix(y); + cl_fixnum q = a / b, r = a % b; + if ((r^b) < 0 && r) { /* opposite sign and some remainder*/ + VALUES(0) = MAKE_FIXNUM(q-1); + VALUES(1) = MAKE_FIXNUM(r+b); + } else { + VALUES(0) = MAKE_FIXNUM(q); + VALUES(1) = MAKE_FIXNUM(r); + } + break; + } + case t_bignum: { /* FIX / BIG */ + if (number_plusp(x) != number_plusp(y)) { + VALUES(0) = MAKE_FIXNUM(-1); + VALUES(1) = number_plus(y, x); + } else { + VALUES(0) = MAKE_FIXNUM(0); + VALUES(1) = x; + } + break; + } + case t_ratio: /* FIX / RAT */ + floor2(number_times(x, y->ratio.den), y->ratio.num); + VALUES(1) = make_ratio(VALUES(1), y->ratio.den); + break; + case t_shortfloat: { /* FIX / SF */ + float n = sf(y); + float p = fix(x) / n; + float q = floorf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* FIX / LF */ + double n = lf(y); + double p = fix(x) / n; + double q = floor(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(y); + } + break; + case t_bignum: + switch(type_of(y)) { + case t_fixnum: { /* BIG / FIX */ + cl_object q = big_register0_get(); + cl_object r = big_register1_get(); + cl_object j = big_register2_get(); + mpz_set_si(j->big.big_num, fix(y)); + mpz_fdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, j->big.big_num); + VALUES(0) = big_register_normalize(q); + VALUES(1) = big_register_normalize(r); + break; + } + case t_bignum: { /* BIG / BIG */ + cl_object q = big_register0_get(); + cl_object r = big_register1_get(); + mpz_fdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, y->big.big_num); + VALUES(0) = big_register_normalize(q); + VALUES(1) = big_register_normalize(r); + break; + } + case t_ratio: /* BIG / RAT */ + floor2(number_times(x, y->ratio.den), y->ratio.num); + VALUES(1) = make_ratio(VALUES(1), y->ratio.den); + break; + case t_shortfloat: { /* BIG / SF */ + float n = sf(y); + float p = big_to_double(x) / n; + float q = floorf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* BIG / LF */ + double n = lf(y); + double p = big_to_double(x) / n; + double q = floor(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(y); + } + break; + case t_ratio: + switch(type_of(y)) { + case t_ratio: /* RAT / RAT */ + floor2(number_times(x->ratio.num, y->ratio.den), + number_times(x->ratio.den, y->ratio.num)); + VALUES(1) = make_ratio(VALUES(1), number_times(x->ratio.den, y->ratio.den)); + break; + default: /* RAT / ANY */ + floor2(x->ratio.num, number_times(x->ratio.den, y)); + VALUES(1) = make_ratio(VALUES(1), x->ratio.den); + } + break; + case t_shortfloat: { /* SF / ANY */ + float n = number_to_double(y); + float p = sf(x)/n; + float q = floorf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* LF / ANY */ + double n = number_to_double(y); + double p = lf(x)/n; + double q = floor(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +@(defun floor (x &optional (y OBJNULL)) +@ + if (narg == 1) + floor1(x); + else + floor2(x, y); + returnn(VALUES(0)); +@) + +cl_object +ceiling1(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + VALUES(0) = x; + VALUES(1) = MAKE_FIXNUM(0); + break; + case t_ratio: + VALUES(0) = ceiling2(x->ratio.num, x->ratio.den); + VALUES(1) = make_ratio(VALUES(1), x->ratio.den); + break; + case t_shortfloat: { + double d = (double)(sf(x)); + double y = ceil(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_shortfloat(d - y); + break; + } + case t_longfloat: { + double d = (double)(sf(x)); + double y = ceil(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_longfloat(d - y); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +cl_object +ceiling2(cl_object x, cl_object y) +{ + switch(type_of(x)) { + case t_fixnum: + switch(type_of(y)) { + case t_fixnum: { /* FIX / FIX */ + cl_fixnum a = fix(x); cl_fixnum b = fix(y); + cl_fixnum q = a / b; cl_fixnum r = a % b; + if ((r^b) > 0 && r) { /* same signs and some remainder */ + VALUES(0) = MAKE_FIXNUM(q+1); + VALUES(1) = MAKE_FIXNUM(r-b); + } else { + VALUES(0) = MAKE_FIXNUM(q); + VALUES(1) = MAKE_FIXNUM(r); + } + break; + } + case t_bignum: { /* FIX / BIG */ + if (number_plusp(x) != number_plusp(y)) { + VALUES(0) = MAKE_FIXNUM(0); + VALUES(1) = x; + } else { + VALUES(0) = MAKE_FIXNUM(1); + VALUES(1) = number_minus(x, y); + } + break; + } + case t_ratio: /* FIX / RAT */ + ceiling2(number_times(x, y->ratio.den), y->ratio.num); + VALUES(1) = make_ratio(VALUES(1), y->ratio.den); + break; + case t_shortfloat: { /* FIX / SF */ + float n = sf(y); + float p = fix(x)/n; + float q = ceilf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* FIX / LF */ + double n = lf(y); + double p = fix(x)/n; + double q = ceil(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(y); + } + break; + case t_bignum: + switch(type_of(y)) { + case t_fixnum: { /* BIG / FIX */ + cl_object q = big_register0_get(); + cl_object r = big_register1_get(); + cl_object j = big_register2_get(); + mpz_set_si(j->big.big_num, fix(y)); + mpz_cdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, j->big.big_num); + VALUES(0) = big_register_normalize(q); + VALUES(1) = big_register_normalize(r); + break; + } + case t_bignum: { /* BIG / BIG */ + cl_object q = big_register0_get(); + cl_object r = big_register1_get(); + mpz_cdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, y->big.big_num); + VALUES(0) = big_register_normalize(q); + VALUES(1) = big_register_normalize(r); + break; + } + case t_ratio: /* BIG / RAT */ + ceiling2(number_times(x, y->ratio.den), y->ratio.num); + VALUES(1) = make_ratio(VALUES(1), y->ratio.den); + break; + case t_shortfloat: { /* BIG / SF */ + float n = sf(y); + float p = big_to_double(x)/n; + float q = ceilf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* BIG / LF */ + double n = lf(y); + double p = big_to_double(x)/n; + double q = ceil(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(y); + } + break; + case t_ratio: + switch(type_of(y)) { + case t_ratio: /* RAT / RAT */ + ceiling2(number_times(x->ratio.num, y->ratio.den), + number_times(x->ratio.den, y->ratio.num)); + VALUES(1) = make_ratio(VALUES(1), number_times(x->ratio.den, y->ratio.den)); + break; + default: /* RAT / ANY */ + ceiling2(x->ratio.num, number_times(x->ratio.den, y)); + VALUES(1) = number_divide(VALUES(1), x->ratio.den); + } + break; + case t_shortfloat: { /* SF / ANY */ + float n = number_to_double(y); + float p = sf(x)/n; + float q = ceilf(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_shortfloat((p - q)*n); + break; + } + case t_longfloat: { /* LF / ANY */ + double n = number_to_double(y); + double p = lf(x)/n; + double q = ceil(p); + VALUES(0) = double_to_integer(q); + VALUES(1) = make_longfloat((p - q)*n); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +@(defun ceiling (x &optional (y OBJNULL)) +@ + if (narg == 1) + ceiling1(x); + else + ceiling2(x, y); + returnn(VALUES(0)); +@) + +cl_object +truncate1(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + VALUES(0) = x; + VALUES(1) = MAKE_FIXNUM(0); + break; + case t_ratio: + VALUES(0) = truncate2(x->ratio.num, x->ratio.den); + VALUES(1) = make_ratio(VALUES(1), x->ratio.den); + break; + case t_shortfloat: { + float d = sf(x); + float y = d > 0? floorf(d) : ceilf(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_shortfloat(d - y); + break; + } + case t_longfloat: { + double d = lf(x); + double y = d > 0? floor(d) : ceil(d); + VALUES(0) = double_to_integer(y); + VALUES(1) = make_longfloat(d - y); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +cl_object +truncate2(cl_object x, cl_object y) +{ + if (number_plusp(x) != number_plusp(y)) + return ceiling2(x, y); + else + return floor2(x, y); +} + +@(defun truncate (x &optional (y OBJNULL)) +@ + if (narg == 1) + truncate1(x); + else + truncate2(x, y); + returnn(VALUES(0)); +@) + +cl_object +round1(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + VALUES(0) = x; + VALUES(1) = MAKE_FIXNUM(0); + break; + case t_ratio: + return round2(x->ratio.num, x->ratio.den); + case t_shortfloat: { + double d = (double)(sf(x)); + cl_object q = double_to_integer(d + (d>=0? 0.5 : -0.5)); + d -= number_to_double(q); + if (d == 0.5) { + if (number_oddp(q)) { + q = one_plus(q); + d = -0.5; + } + } else if (d == -0.5) { + if (number_oddp(q)) { + q = one_minus(q); + d = 0.5; + } + } + VALUES(0) = q; + VALUES(1) = make_shortfloat(d); + break; + } + case t_longfloat: { + double d = lf(x); + cl_object q = double_to_integer(d + (d>=0? 0.5 : -0.5)); + d -= number_to_double(q); + if (d == 0.5) { + if (number_oddp(q)) { + q = one_plus(q); + d = -0.5; + } + } else if (d == -0.5) { + if (number_oddp(q)) { + q = one_minus(q); + d = 0.5; + } + } + VALUES(0) = q; + VALUES(1) = make_longfloat(d); + break; + } + default: + FEtype_error_real(x); + } + NValues = 2; + return VALUES(0); +} + +cl_object +round2(cl_object x, cl_object y) +{ + cl_object q; + + q = number_divide(x, y); + switch (type_of(q)) { + case t_fixnum: + case t_bignum: + VALUES(0) = q; + VALUES(1) = MAKE_FIXNUM(0); + break; + case t_ratio: { + cl_object q1 = integer_divide(q->ratio.num, q->ratio.den); + cl_object r = number_minus(q, q1); + int c = number_compare(r, plus_half); + if (c > 0 || (c == 0 && number_oddp(q1))) { + q1 = one_plus(q1); + } else if (c < 0 || (c == 0 && number_oddp(q1))) { + q1 = one_minus(q1); + } + VALUES(0) = q1; + VALUES(1) = number_remainder(x, y, q1); + break; + } + case t_shortfloat: + case t_longfloat: { + double d = number_to_double(q); + cl_object q1 = double_to_integer(d + (d >= 0.0 ? 0.5 : -0.5)); + d -= number_to_double(q1); + if (d == 0.5 && number_oddp(q1)) + q1 = one_plus(q1); + if (d == -0.5 && number_oddp(q1)) + q1 = one_minus(q1); + VALUES(0) = q1; + VALUES(1) = number_remainder(x, y, q1); + break; + } + default: + FEerror("Complex arguments to round2 (~S, ~S)", 2, x, y); + } + NValues = 2; + return VALUES(0); +} + +@(defun round (x &optional (y OBJNULL)) +@ + if (narg == 1) + round1(x); + else + round2(x, y); + returnn(VALUES(0)); +@) + + +@(defun mod (x y) +@ + /* INV: #'floor always outputs two values */ + Lfloor(2, x, y); + @(return VALUES(1)) +@) + + +@(defun rem (x y) +@ + Ltruncate(2, x, y); + @(return VALUES(1)) +@) + + +@(defun decode_float (x) + double d; + int e, s; + enum cl_type tx = type_of(x); +@ + switch (tx) { + case t_shortfloat: + d = sf(x); break; + case t_longfloat: + d = lf(x); break; + default: + FEtype_error_float(x); + } + if (d >= 0.0) + s = 1; + else { + d = -d; + s = -1; + } + e = double_exponent(d); + set_exponent(&d, 0); + if (tx == t_shortfloat) { + @(return make_shortfloat(d) + MAKE_FIXNUM(e) + make_shortfloat(s)) + } else { + @(return make_longfloat(d) + MAKE_FIXNUM(e) + make_longfloat(s)) + } +@) + + +@(defun scale_float (x y) + double d; + int e, k; + enum cl_type tx = type_of(x); +@ + if (FIXNUMP(y)) + k = fix(y); + else + FEerror("~S is an illegal exponent.", 1, y); + switch (tx) { + case t_shortfloat: + d = sf(x); break; + case t_longfloat: + d = lf(x); break; + default: + FEtype_error_float(x); + } + e = double_exponent(d) + k; +#if defined(VAX) || defined(TAHOE) + if (e <= -128 || e >= 128) +#endif +#ifdef IEEEFLOAT + if (tx == t_shortfloat && (e <= -126 || e >= 130) || + tx == t_longfloat && (e <= -1022 || e >= 1026)) +#endif IEEEFLOAT + FEerror("~S is an illegal exponent.", 1, y); + set_exponent(&d, e); + @(return ((tx == t_shortfloat) ? make_shortfloat(d) + : make_longfloat(d))) +@) + + +@(defun float_radix (x) + enum cl_type t = type_of(x); +@ + if (t != t_shortfloat && t != t_longfloat) + FEtype_error_float(x); + @(return MAKE_FIXNUM(2)) +@) + + +@(defun float_sign (x &optional (y x)) + int negativep; +@ + switch (type_of(x)) { + case t_shortfloat: + negativep = sf(x) < 0; break; + case t_longfloat: + negativep = lf(x) < 0; break; + default: + FEtype_error_float(x); + } + switch (type_of(y)) { + case t_shortfloat: { + float f = sf(y); + @(return make_shortfloat(negativep? -fabsf(f) : fabsf(f))) + } + case t_longfloat: { + double f = lf(y); + @(return make_longfloat(negativep? -fabs(f) : fabs(f))) + } + default: + FEtype_error_float(x); + } +@) + +@(defun float_digits (x) +@ + switch (type_of(x)) { + case t_shortfloat: + x = MAKE_FIXNUM(6); + break; + case t_longfloat: + x = MAKE_FIXNUM(14); + break; + default: + FEtype_error_float(x); + } + @(return x) +@) + + +@(defun float_precision (x) +@ + switch (type_of(x)) { + case t_shortfloat: + @(return ((sf(x) == 0.0) ? MAKE_FIXNUM(0) : MAKE_FIXNUM(24))) + case t_longfloat: + @(return ((lf(x) == 0.0) ? MAKE_FIXNUM(0) : MAKE_FIXNUM(53))) + default: + FEtype_error_float(x); + } +@) + + +@(defun integer_decode_float (x) + int h, l, e, s; +@ + switch (type_of(x)) { + case t_longfloat: + integer_decode_double(lf(x), &h, &l, &e, &s); + x = (h != 0) ? bignum2(h, l) : MAKE_FIXNUM(l); + break; + case t_shortfloat: + integer_decode_float((double)(sf(x)), &h, &e, &s); + x = MAKE_FIXNUM(h); + break; + default: + FEtype_error_float(x); + } + @(return x MAKE_FIXNUM(e) MAKE_FIXNUM(s)) +@) + + +@(defun complex (r &optional (i MAKE_FIXNUM(0))) +@ /* INV: make_complex() checks types */ + @(return make_complex(r, i)) +@) + + +@(defun realpart (x) +@ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + case t_shortfloat: + case t_longfloat: + break; + case t_complex: + x = x->complex.real; + break; + default: + FEtype_error_number(x); + } + @(return x) +@) + + +@(defun imagpart (x) +@ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + x = MAKE_FIXNUM(0); + break; + case t_shortfloat: + x = shortfloat_zero; + break; + case t_longfloat: + x = longfloat_zero; + break; + case t_complex: + x = x->complex.imag; + break; + default: + FEtype_error_number(x); + } + @(return x) +@) + +void +init_num_co(void) +{ + float smallest_float, biggest_float; + double smallest_double, biggest_double; + float float_epsilon, float_negative_epsilon; + double double_epsilon, double_negative_epsilon; + double lf1, lf2; + float sf1, sf2; + cl_object num; + +#define LF_EQL(a,b) (lf1 = a, lf2 = b, lf1 == lf2) +#define SF_EQL(a,b) (sf1 = a, sf2 = b, sf1 == sf2) + +#ifdef VAX + l[0] = 0x80; + l[1] = 0; + smallest_float = *(float *)l; + smallest_double = *(double *)l; +#endif VAX + +#ifdef IEEEFLOAT + ((int *) &smallest_float)[0]= 1; + ((int *) &smallest_double)[HIND] = 0; + ((int *) &smallest_double)[LIND] = 1; +#endif IEEEFLOAT + +#ifdef VAX + l[0] = 0xffff7fff; + l[1] = 0xffffffff; + biggest_float = *(float *)l; + biggest_double = *(double *)l; +#endif VAX + +#ifdef IEEEFLOAT + ((unsigned int *) &biggest_float)[0]= (unsigned int)0x7f7fffff; + ((unsigned int *) &biggest_double)[HIND] = (unsigned int)0x7fefffff; + ((unsigned int *) &biggest_double)[LIND] = (unsigned int)0xffffffff; +#endif IEEEFLOAT + +#ifdef TAHOE + l[0] = 0x00800000; + l[1] = 0; + smallest_float = *(float *)l; + smallest_double = *(double *)l; +#endif + +/* We want the smallest number not satisfying something, + and so we go quickly down, and then back up. We have + to use a function call for test, since in line code may keep + too much precision, while the usual lisp eql,is not + in line. + We use SMALL as a multiple to come back up by. +*/ + +#define SMALL 1.05 + + for (float_epsilon = 1.0; + !SF_EQL((float)(1.0 + float_epsilon),(float)1.0); + float_epsilon /= 2.0) + ; + while(SF_EQL((float)(1.0 + float_epsilon),(float)1.0)) + float_epsilon=float_epsilon*SMALL; + for (float_negative_epsilon = 1.0; + !SF_EQL((float)(1.0 - float_negative_epsilon) ,(float)1.0); + float_negative_epsilon /= 2.0) + ; + while(SF_EQL((float)(1.0 - float_negative_epsilon) ,(float)1.0)) + float_negative_epsilon=float_negative_epsilon*SMALL; + for (double_epsilon = 1.0; + !(LF_EQL(1.0 + double_epsilon, 1.0)); + double_epsilon /= 2.0) + ; + while((LF_EQL(1.0 + double_epsilon, 1.0))) + double_epsilon=double_epsilon*SMALL; + ; + for (double_negative_epsilon = 1.0; + !LF_EQL(1.0 - double_negative_epsilon , 1.0); + double_negative_epsilon /= 2.0) + ; + while(LF_EQL(1.0 - double_negative_epsilon , 1.0)) + double_negative_epsilon=double_negative_epsilon*SMALL; + ; + + num = make_shortfloat(biggest_float); + make_constant("MOST-POSITIVE-SHORT-FLOAT", num); + make_constant("MOST-POSITIVE-SINGLE-FLOAT", num); + + num = make_shortfloat(smallest_float); + make_constant("LEAST-POSITIVE-SHORT-FLOAT", num); + make_constant("LEAST-POSITIVE-SINGLE-FLOAT", num); + + num = make_shortfloat(-smallest_float); + make_constant("LEAST-NEGATIVE-SHORT-FLOAT", num); + make_constant("LEAST-NEGATIVE-SINGLE-FLOAT", num); + + num = make_shortfloat(-biggest_float); + make_constant("MOST-NEGATIVE-SHORT-FLOAT", num); + make_constant("MOST-NEGATIVE-SINGLE-FLOAT", num); + + num = make_longfloat(biggest_double); + make_constant("MOST-POSITIVE-DOUBLE-FLOAT", num); + make_constant("MOST-POSITIVE-LONG-FLOAT", num); + + num = make_longfloat(smallest_double); + make_constant("LEAST-POSITIVE-DOUBLE-FLOAT", num); + make_constant("LEAST-POSITIVE-LONG-FLOAT", num); + + num = make_longfloat(-smallest_double); + make_constant("LEAST-NEGATIVE-DOUBLE-FLOAT", num); + make_constant("LEAST-NEGATIVE-LONG-FLOAT", num); + + num = make_longfloat(-biggest_double); + make_constant("MOST-NEGATIVE-DOUBLE-FLOAT", num); + make_constant("MOST-NEGATIVE-LONG-FLOAT", num); + + num = make_shortfloat(float_epsilon); + make_constant("SHORT-FLOAT-EPSILON", num); + make_constant("SINGLE-FLOAT-EPSILON", num); + num = make_longfloat(double_epsilon); + make_constant("DOUBLE-FLOAT-EPSILON", num); + make_constant("LONG-FLOAT-EPSILON", num); + + num = make_shortfloat(float_negative_epsilon); + make_constant("SHORT-FLOAT-NEGATIVE-EPSILON", num); + make_constant("SINGLE-FLOAT-NEGATIVE-EPSILON", num); + num = make_longfloat(double_negative_epsilon); + make_constant("DOUBLE-FLOAT-NEGATIVE-EPSILON", num); + make_constant("LONG-FLOAT-NEGATIVE-EPSILON", num); + + plus_half = make_ratio(MAKE_FIXNUM(1), MAKE_FIXNUM(2)); + register_root(&plus_half); + + minus_half = make_ratio(MAKE_FIXNUM(-1), MAKE_FIXNUM(2)); + register_root(&minus_half); +} diff --git a/src/c/num_comp.d b/src/c/num_comp.d new file mode 100644 index 000000000..3cab2bd5a --- /dev/null +++ b/src/c/num_comp.d @@ -0,0 +1,332 @@ +/* + num_comp.c -- Comparisons on numbers. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +/* + For sake of profiler, put Lall_the_same before number_compare, + so that all calls to number_compare are attributed to function =. + Similarly for Lmonotonically_decreasing. +*/ + + +@(defun all_the_same (num &rest nums) + int i; + cl_object numi; +@ + /* ANSI: Need not signal error for 1 argument */ + /* INV: For >= 2 arguments, number_equalp() performs checks */ + for (i = 1; i < narg; i++) { + numi = va_arg(nums, cl_object); + if (!number_equalp(num, numi)) + @(return Cnil) + } + @(return Ct) +@) + +/* Returns 1 if both numbers compare to equal */ +int +number_equalp(cl_object x, cl_object y) +{ + double dx; + + /* INV: (= fixnum bignum) => 0 */ + /* INV: (= fixnum ratio) => 0 */ + /* INV: (= bignum ratio) => 0 */ + switch (type_of(x)) { + case t_fixnum: + switch (type_of(y)) { + case t_fixnum: + return x == y; + case t_bignum: + case t_ratio: + return 0; + case t_shortfloat: + return fix(x) == sf(y); + case t_longfloat: + return fix(x) == lf(y); + case t_complex: + goto Y_COMPLEX; + default: + FEtype_error_number(y); + } + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + return 0; + case t_bignum: + return big_compare(x, y)==0; + case t_ratio: + return 0; + case t_shortfloat: + return sf(y) == number_to_double(x); + case t_longfloat: + return lf(y) == number_to_double(x); + case t_complex: + goto Y_COMPLEX; + default: + FEtype_error_number(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + return 0; + case t_ratio: + return (number_equalp(x->ratio.num, y->ratio.num) && + number_equalp(x->ratio.den, x->ratio.den)); + case t_shortfloat: + return sf(y) == number_to_double(x); + case t_longfloat: + return lf(y) == number_to_double(x); + case t_complex: + goto Y_COMPLEX; + default: + FEtype_error_number(y); + } + case t_shortfloat: + dx = sf(x); + goto FLOAT; + case t_longfloat: + dx = lf(x); + FLOAT: + switch (type_of(y)) { + case t_fixnum: + return dx == fix(y); + case t_bignum: + case t_ratio: + return dx == number_to_double(y); + case t_shortfloat: + return dx == sf(y); + case t_longfloat: + return dx == lf(y); + case t_complex: + goto Y_COMPLEX; + default: + FEtype_error_number(y); + } + Y_COMPLEX: + if (!number_zerop(y->complex.imag)) + return 0; + return number_equalp(x, y->complex.real); + case t_complex: + if (type_of(y) == t_complex) + return (number_equalp(x->complex.real, y->complex.real) && + number_equalp(x->complex.imag, y->complex.imag)); + if (REAL_TYPE(type_of(y))) { + if (number_zerop(x->complex.imag)) + return number_equalp(x->complex.real, y) != 0; + else + return 0; + } + FEtype_error_number(y); + default: + FEtype_error_number(x); + } +} + +/* + The value of number_compare(x, y) is + + -1 if x < y + 0 if x = y + 1 if x > y. + + If x or y is not real, it fails. +*/ +int +number_compare(cl_object x, cl_object y) +{ + int ix, iy; + double dx, dy; + + switch (type_of(x)) { + case t_fixnum: + ix = fix(x); + switch (type_of(y)) { + case t_fixnum: + iy = fix(y); + if (ix < iy) + return(-1); + else return(ix != iy); + case t_bignum: + /* INV: (= x y) can't be zero since fixnum != bignum */ + return big_sign(y) < 0? 1 : -1; + case t_ratio: + x = number_times(x, y->ratio.den); + y = y->ratio.num; + return(number_compare(x, y)); + case t_shortfloat: + dx = (double)(ix); + dy = (double)(sf(y)); + goto LONGFLOAT; + case t_longfloat: + dx = (double)(ix); + dy = lf(y); + goto LONGFLOAT; + default: + FEtype_error_real(y); + } + case t_bignum: + switch (type_of(y)) { + case t_fixnum: + return big_sign(x) < 0 ? -1 : 1; + case t_bignum: + return(big_compare(x, y)); + case t_ratio: + x = number_times(x, y->ratio.den); + y = y->ratio.num; + return(number_compare(x, y)); + case t_shortfloat: + dx = number_to_double(x); + dy = (double)(sf(y)); + goto LONGFLOAT; + case t_longfloat: + dx = number_to_double(x); + dy = lf(y); + goto LONGFLOAT; + default: + FEtype_error_real(y); + } + case t_ratio: + switch (type_of(y)) { + case t_fixnum: + case t_bignum: + y = number_times(y, x->ratio.den); + x = x->ratio.num; + return(number_compare(x, y)); + case t_ratio: + return(number_compare(number_times(x->ratio.num, + y->ratio.den), + number_times(y->ratio.num, + x->ratio.den))); + case t_shortfloat: + dx = number_to_double(x); + dy = (double)(sf(y)); + goto LONGFLOAT; + case t_longfloat: + dx = number_to_double(x); + dy = lf(y); + goto LONGFLOAT; + default: + FEtype_error_real(y); + } + case t_shortfloat: + dx = (double)(sf(x)); + goto LONGFLOAT0; + case t_longfloat: + dx = lf(x); + LONGFLOAT0: + switch (type_of(y)) { + case t_fixnum: + dy = (double)(fix(y)); + break; + case t_bignum: + case t_ratio: + dy = number_to_double(y); + break; + case t_shortfloat: + dy = (double)(sf(y)); + break; + case t_longfloat: + dy = lf(y); + break; + default: + FEtype_error_real(y); + } + LONGFLOAT: + if (dx == dy) + return(0); + else if (dx < dy) + return(-1); + else + return(1); + default: + FEtype_error_real(x); + } +} + +@(defun all_different (&rest nums) + int i, j; + va_list numb; +@ + if (narg == 0) + FEtoo_few_arguments(&narg); + if (narg == 1) + @(return Ct) + for (i = 0; i < narg; i++) { + cl_object numi = va_arg(nums, cl_object); + va_start(numb, narg); + for (j = 0; j < i; j++) + if (number_equalp(numi, va_arg(numb, cl_object))) + @(return Cnil) + } + @(return Ct) +@) + +#define MONOTONIC(i, j) (int narg, ...) \ +{ va_list nums; va_start(nums, narg); \ + return monotonic(i, j, narg, (cl_object *)nums); } + +cl_object +Lmonotonically_nondecreasing MONOTONIC( 1, 0) +cl_object +Lmonotonically_nonincreasing MONOTONIC(-1, 0) +cl_object +Lmonotonically_increasing MONOTONIC( 1, 1) +cl_object +Lmonotonically_decreasing MONOTONIC(-1, 1) + +cl_object +monotonic(int s, int t, int narg, cl_object *nums) +{ + int i; + + if (narg == 0) + FEtoo_few_arguments(&narg); + /* INV: type check occurs in number_compare() */ + for (i = 1; i < narg; i++) + if (s*number_compare(nums[i], nums[i-1]) < t) + return1(Cnil); + return1(Ct); +} + +@(defun max (max &rest nums) + cl_object numi; + int i; +@ + /* INV: type check occurs in number_compare() */ + for (i = 1; i < narg; i++) { + numi = va_arg(nums, cl_object); + if (number_compare(max, numi) < 0) + max = numi; + } + @(return max) +@) + +@(defun min (min &rest nums) + cl_object numi; + int i; +@ + /* INV: type check occurs in number_compare() */ + va_start(nums, min); + for (i = 1; i < narg; i++) { + numi = va_arg(nums, cl_object); + if (number_compare(min, numi) > 0) + min = numi; + } + @(return min) +@) diff --git a/src/c/num_log.d b/src/c/num_log.d new file mode 100644 index 000000000..6f81ce7ce --- /dev/null +++ b/src/c/num_log.d @@ -0,0 +1,693 @@ +/* + num_log.c -- Logical operations on numbers. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +#define BOOLCLR 0 +#define BOOLSET 017 +#define BOOL1 03 +#define BOOL2 05 +#define BOOLC1 014 +#define BOOLC2 012 +#define BOOLAND 01 +#define BOOLIOR 07 +#define BOOLXOR 06 +#define BOOLEQV 011 +#define BOOLNAND 016 +#define BOOLNOR 010 +#define BOOLANDC1 04 +#define BOOLANDC2 02 +#define BOOLORC1 015 +#define BOOLORC2 013 + +/* + x : fixnum or bignum (may be not normalized) + y : integer + returns + fixnum or bignum ( not normalized ) +*/ + +static cl_object big_log_op(struct bignum *x, cl_object y, int (*op)()); + +static cl_object +log_op(int narg, int (*op)(), cl_object *nums) +{ + enum cl_type t; + cl_object x, numi; + int i = 1, j; + + if (narg < 2) FEtoo_few_arguments(&narg); + x = *nums++; + t = type_of(x); + if (t == t_bignum) { + x = big_copy(x); /* since big_log_op clobbers it */ + goto BIG_OP; + } if (t != t_fixnum) { + FEtype_error_integer(x); + } + j = fix(x); + for (; i < narg; i++) { + numi = *nums++; + t = type_of(numi); + if (t == t_bignum) { + x = big_log_op(&bignum1(j)->big, numi, op); + i++; + goto BIG_OP; + } else if (t != t_fixnum) { + FEtype_error_integer(numi); + } + j = (*op)(j, fix(numi)); + } + return(MAKE_FIXNUM(j)); + +BIG_OP: + for (; i < narg; i++) + x = big_log_op(&x->big, *nums++, op); + return(big_normalize(x)); +} +/* + big_log_op(x, y, op) performs the logical operation op on + bignum x and integer y, and returns the result in x destructively. +*/ +static cl_object +big_log_op(struct bignum *x, cl_object y, int (*op)()) +{ + int i, j; + int y_size, x_size = x->big_size; + mp_limb_t *y_limbs, *x_limbs = x->big_limbs; + int y_sign, x_sign = (big_sign((cl_object)x) < 0); + + if (FIXNUMP(y)) { + i = fix(y); + x_limbs[x_size-1] = (*op)(x_limbs[x_size-1], i); + y_sign = (i < 0); + } else if (type_of(y) != t_bignum) { + FEtype_error_integer(y); + } else { + y_sign = big_sign((cl_object)y) < 0; + x_size = abs(x->big_size); + y_size = abs(y->big.big_size); + y_limbs = y->big.big_limbs; + + if (y_size > x_size) { + /* First loop finds the size of the result. */ + for (i = y_size - 1; i >= 0; i--) { + j = (i >= x_size) ? 0 : x_limbs[i]; + if ((*op)(j, y_limbs[i]) != 0) + break; + } + x_size = i + 1; + + /* Handle allocation, now that we know exactly how much space is + needed for the result. */ + if (x->big_dim < x_size) { + _mpz_realloc(x->big_num, x_size); + x_limbs = x->big_limbs; + } + } + /* Second loop computes the real result. */ + for (i = 0 ; i < x_size; i++) + x_limbs[i] = (*op)(x_limbs[i], y_limbs[i]); + } + /* + Set the sign according to operation. + */ + x->big_size = (*op)(x_sign, y_sign)? -x_size : x_size; + return((cl_object)x); +} + +static int +ior_op(int i, int j) +{ + return(i | j); +} + +static int +xor_op(int i, int j) +{ + return(i ^ j); +} + +static int +and_op(int i, int j) +{ + return(i & j); +} + +static int +eqv_op(int i, int j) +{ + return(~(i ^ j)); +} + +static int +nand_op(int i, int j) +{ + return(~(i & j)); +} + +static int +nor_op(int i, int j) +{ + return(~(i | j)); +} + +static int +andc1_op(int i, int j) +{ + return((~i) & j); +} + +static int +andc2_op(int i, int j) +{ + return(i & (~j)); +} + +static int +orc1_op(int i, int j) +{ + return((~i) | j); +} + +static int +orc2_op(int i, int j) +{ + return(i | (~j)); +} + +static int +b_clr_op(int i, int j) +{ + return(0); +} + +static int +b_set_op(int i, int j) +{ + return(-1); +} + +static int +b_1_op(int i, int j) +{ + return(i); +} + +static int +b_2_op(int i, int j) +{ + return(j); +} + +static int +b_c1_op(int i, int j) +{ + return(~i); +} + +static int +b_c2_op(int i, int j) +{ + return(~j); +} + +static int +big_bitp(cl_object x, int p) +{ + if (p < 0) + return 0; + else { +#define BITS_PER_LIMB (sizeof(mp_limb_t)*8) + int size = x->big.big_size; + mp_limb_t *limbs = x->big.big_limbs; + int cell = p / BITS_PER_LIMB; + int bit = p % BITS_PER_LIMB; + if (size > 0) + if (cell > size) + return(size < 0); + else + return (limbs[cell] >> bit) & 1; + else { + mp_size_t zero_bound; + size = -size; + /* Locate the least significant non-zero limb. */ + for (zero_bound = 0; limbs[zero_bound] == 0; zero_bound++) + ; + if (cell > size) + return 1; + else if (cell < zero_bound) + return 0; + else if (cell == zero_bound) + return (-limbs[cell] >> bit) & 1; + else /* cell > zero_bound */ + return (~limbs[cell] >> bit) & 1; + } + } +} + +@(defun lognot (x) +@ + return Llogxor(1,x,MAKE_FIXNUM(-1)); +@) + +static int +count_bits(cl_object x) +{ + cl_fixnum count; + + switch (type_of(x)) { + case t_fixnum: { + cl_fixnum i = fix(x); + cl_fixnum j = (i < 0) ? ~i : i; + for (count=0 ; j ; j >>= 1) + if (j & 1) count++; + break; + } + case t_bignum: + if (big_sign(x) < 0) { + Llognot(1,x); + VALUES(0) = x; + } + count = mpz_popcount(x->big.big_num); + break; + default: + FEtype_error_integer(x); + } + return count; +} + +/* + Left shift if w > 0, right shift if w < 0. + */ +cl_object +integer_shift(cl_object x, int w) +{ + cl_object y; + int cell, bits, i; + + if (w == 0) return(x); + cell = w / 32; + bits = w % 32; + if (FIXNUMP(x)) { + i = fix(x); + if (i == 0) return(x); + if (cell == 0) { + if (w < 0) { + if (i >= 0) + return(MAKE_FIXNUM(i >> -w)); + else + return(MAKE_FIXNUM(~((~i) >> -w))); + } + if (i > 0) { + if (((~MOST_POSITIVE_FIX >> w) & i) == 0) + return(MAKE_FIXNUM(i << w)); + } else { + if (((MOST_NEGATIVE_FIX >> w) & ~i) == 0) + return(MAKE_FIXNUM(i << w)); + } + } + x = bignum1(i); + } + y = big_register0_get(); + if (w < 0) { + mpz_div_2exp(y->big.big_num, x->big.big_num, -w); + } else { + mpz_mul_2exp(y->big.big_num, x->big.big_num, w); + } + return(big_register_normalize(y)); +} + +int +int_bit_length(int i) +{ + register int count, j; + + count = 0; + for (j = 0; j < 31 ; j++) + if (((i >> j) & 1) == 1) count = j + 1; + return(count); +} + +@(defun logior (&rest nums) +@ + if (narg == 0) + @(return MAKE_FIXNUM(0)) + /* INV: log_op() checks types */ + if (narg == 1) + @(return va_arg(nums, cl_object)) + @(return log_op(narg, ior_op, (cl_object *)nums)) +@) + +@(defun logxor (&rest nums) +@ + if (narg == 0) + @(return MAKE_FIXNUM(0)) + /* INV: log_op() checks types */ + if (narg == 1) + @(return va_arg(nums, cl_object)) + @(return log_op(narg, xor_op, (cl_object *)nums)) +@) + +@(defun logand (&rest nums) +@ + if (narg == 0) + @(return MAKE_FIXNUM(-1)) + /* INV: log_op() checks types */ + if (narg == 1) + @(return va_arg(nums, cl_object)) + @(return log_op(narg, and_op, (cl_object *)nums)) +@) + +@(defun logeqv (&rest nums) +@ + if (narg == 0) + @(return MAKE_FIXNUM(-1)) + /* INV: log_op() checks types */ + if (narg == 1) + @(return va_arg(nums, cl_object)) + @(return log_op(narg, eqv_op, (cl_object *)nums)) +@) + +@(defun boole (o &rest nums) + int (*op)(); +@ + /* FIXME! Is this check ok? */ + check_arg(3); + /* INV: log_op() checks types */ + switch(fixint(o)) { + case BOOLCLR: op = b_clr_op; break; + case BOOLSET: op = b_set_op; break; + case BOOL1: op = b_1_op; break; + case BOOL2: op = b_2_op; break; + case BOOLC1: op = b_c1_op; break; + case BOOLC2: op = b_c2_op; break; + case BOOLAND: op = and_op; break; + case BOOLIOR: op = ior_op; break; + case BOOLXOR: op = xor_op; break; + case BOOLEQV: op = eqv_op; break; + case BOOLNAND: op = nand_op; break; + case BOOLNOR: op = nor_op; break; + case BOOLANDC1: op = andc1_op; break; + case BOOLANDC2: op = andc2_op; break; + case BOOLORC1: op = orc1_op; break; + case BOOLORC2: op = orc2_op; break; + default: + FEerror("~S is an invalid logical operator.", + 1, o); + } + @(return log_op(2, op, (cl_object *)nums)) +@) + +@(defun logbitp (p x) + bool i; +@ + assert_type_non_negative_integer(p); + assert_type_integer(x); + if (FIXNUMP(p)) + if (FIXNUMP(x)) + i = ((fix(x) >> fix(p)) & 1); + else + i = big_bitp(x, fix(p)); + else if (FIXNUMP(x)) + i = (fix(x) < 0); + else + i = (big_sign(x) < 0); + @(return (i ? Ct : Cnil)) +@) + +@(defun ash (x y) + cl_object r; + int sign_x; +@ + assert_type_integer(x); + assert_type_integer(y); + if (FIXNUMP(y)) + r = integer_shift(x, fix(y)); + else { + /* + bit position represented by bignum is probably + out of our address space. So, result is returned + according to sign of integer. + */ + if (FIXNUMP(x)) + if (fix(x) > 0) + sign_x = 1; + else if (fix(x) == 0) + sign_x = 0; + else + sign_x = -1; + else + sign_x = big_sign(x); + if (big_sign(y) < 0) + if (sign_x < 0) + r = MAKE_FIXNUM(-1); + else + r = MAKE_FIXNUM(0); + else if (sign_x == 0) + r = x; + else + FEerror("Insufficient memory.", 0); + } + @(return r) +@) + +@(defun logcount (x) +@ + @(return MAKE_FIXNUM(count_bits(x))) +@) + +@(defun integer_length (x) + int count, i; +@ + switch (type_of(x)) { + case t_fixnum: + i = fix(x); + count = int_bit_length((i < 0) ? ~i : i); + break; + case t_bignum: { + int last = abs(x->big.big_size) - 1; + i = x->big.big_limbs[last]; + count = last * (sizeof(mp_limb_t) * 8) + int_bit_length(i); + break; + } + default: + FEtype_error_integer(x); + } + @(return MAKE_FIXNUM(count)) +@) + +void +init_num_log(void) +{ + make_constant("BOOLE-CLR", MAKE_FIXNUM(BOOLCLR)); + make_constant("BOOLE-SET", MAKE_FIXNUM(BOOLSET)); + make_constant("BOOLE-1", MAKE_FIXNUM(BOOL1)); + make_constant("BOOLE-2", MAKE_FIXNUM(BOOL2)); + make_constant("BOOLE-C1", MAKE_FIXNUM(BOOLC1)); + make_constant("BOOLE-C2", MAKE_FIXNUM(BOOLC2)); + make_constant("BOOLE-AND", MAKE_FIXNUM(BOOLAND)); + make_constant("BOOLE-IOR", MAKE_FIXNUM(BOOLIOR)); + make_constant("BOOLE-XOR", MAKE_FIXNUM(BOOLXOR)); + make_constant("BOOLE-EQV", MAKE_FIXNUM(BOOLEQV)); + make_constant("BOOLE-NAND", MAKE_FIXNUM(BOOLNAND)); + make_constant("BOOLE-NOR", MAKE_FIXNUM(BOOLNOR)); + make_constant("BOOLE-ANDC1", MAKE_FIXNUM(BOOLANDC1)); + make_constant("BOOLE-ANDC2", MAKE_FIXNUM(BOOLANDC2)); + make_constant("BOOLE-ORC1", MAKE_FIXNUM(BOOLORC1)); + make_constant("BOOLE-ORC2", MAKE_FIXNUM(BOOLORC2)); +} + +@(defun si::bit_array_op (o x y r) + cl_fixnum i, j, n, d; + cl_object r0; + int (*op)(); + bool replace = FALSE; + int xi, yi, ri; + byte *xp, *yp, *rp; + int xo, yo, ro; +@ + if (type_of(x) == t_bitvector) { + d = x->vector.dim; + xp = x->vector.self.bit; + xo = x->vector.offset; + if (type_of(y) != t_bitvector) + goto ERROR; + if (d != y->vector.dim) + goto ERROR; + yp = y->vector.self.bit; + yo = y->vector.offset; + if (r == Ct) + r = x; + if (r != Cnil) { + if (type_of(r) != t_bitvector) + goto ERROR; + if (r->vector.dim != d) + goto ERROR; + i = (r->vector.self.bit - xp)*8 + (r->vector.offset - xo); + if ((i > 0 && i < d) || (i < 0 && -i < d)) { + r0 = r; + r = Cnil; + replace = TRUE; + goto L1; + } + i = (r->vector.self.bit - yp)*8 + (r->vector.offset - yo); + if ((i > 0 && i < d) || (i < 0 && -i < d)) { + r0 = r; + r = Cnil; + replace = TRUE; + } + } + L1: + if (Null(r)) { + r = siLmake_vector(6, Sbit, MAKE_FIXNUM(d), Cnil, Cnil, Cnil, Cnil); + } + } else { + if (type_of(x) != t_array) + goto ERROR; + if ((enum aelttype)x->array.elttype != aet_bit) + goto ERROR; + d = x->array.dim; + xp = x->vector.self.bit; + xo = x->vector.offset; + if (type_of(y) != t_array) + goto ERROR; + if ((enum aelttype)y->array.elttype != aet_bit) + goto ERROR; + if (x->array.rank != y->array.rank) + goto ERROR; + yp = y->vector.self.bit; + yo = y->vector.offset; + for (i = 0; i < x->array.rank; i++) + if (x->array.dims[i] != y->array.dims[i]) + goto ERROR; + if (r == Ct) + r = x; + if (r != Cnil) { + if (type_of(r) != t_array) + goto ERROR; + if ((enum aelttype)r->array.elttype != aet_bit) + goto ERROR; + if (r->array.rank != x->array.rank) + goto ERROR; + for (i = 0; i < x->array.rank; i++) + if (r->array.dims[i] != x->array.dims[i]) + goto ERROR; + i = (r->vector.self.bit - xp)*8 + (r->vector.offset - xo); + if ((i > 0 && i < d) || (i < 0 && -i < d)) { + r0 = r; + r = Cnil; + replace = TRUE; + goto L2; + } + i = (r->vector.self.bit - yp)*8 + (r->vector.offset - yo); + if ((i > 0 && i < d) || (i < 0 && -i < d)) { + r0 = r; + r = Cnil; + replace = TRUE; + } + } + L2: + if (Null(r)) { + r = alloc_object(t_array); + r->array.self.t = NULL; + r->array.displaced = Cnil; + r->array.rank = 1; + r->array.dims = NULL; + r->array.elttype = get_aelttype(Sbit); + r->array.dims = alloc_atomic_align(sizeof(int), sizeof(int)); + r->array.dim = x->array.dim; + r->array.adjustable = FALSE; + array_allocself(r); + } + } + rp = r->vector.self.bit; + ro = r->vector.offset; + switch(fixint(o)) { + case BOOLCLR: op = b_clr_op; break; + case BOOLSET: op = b_set_op; break; + case BOOL1: op = b_1_op; break; + case BOOL2: op = b_2_op; break; + case BOOLC1: op = b_c1_op; break; + case BOOLC2: op = b_c2_op; break; + case BOOLAND: op = and_op; break; + case BOOLIOR: op = ior_op; break; + case BOOLXOR: op = xor_op; break; + case BOOLEQV: op = eqv_op; break; + case BOOLNAND: op = nand_op; break; + case BOOLNOR: op = nor_op; break; + case BOOLANDC1: op = andc1_op; break; + case BOOLANDC2: op = andc2_op; break; + case BOOLORC1: op = orc1_op; break; + case BOOLORC2: op = orc2_op; break; + default: + FEerror("~S is an invalid logical operator.", 1, o); + } + +#define set_high(place, nbits, value) \ + (place)=((place)&~(-0400>>(nbits)))|((value)&(-0400>>(nbits))) + +#define set_low(place, nbits, value) \ + (place)=((place)&(-0400>>(8-(nbits))))|((value)&~(-0400>>(8-(nbits)))) + +#define extract_byte(integer, pointer, index, offset) \ + (integer) = (pointer)[(index)+1] & 0377; \ + (integer) = ((pointer)[index]<<(offset))|((integer)>>(8-(offset))) + +#define store_byte(pointer, index, offset, value) \ + set_low((pointer)[index], 8-(offset), (value)>>(offset)); \ + set_high((pointer)[(index)+1], offset, (value)<<(8-(offset))) + + if (xo == 0 && yo == 0 && ro == 0) { + for (n = d/8, i = 0; i < n; i++) + rp[i] = (*op)(xp[i], yp[i]); + if ((j = d%8) > 0) + set_high(rp[n], j, (*op)(xp[n], yp[n])); + if (!replace) + @(return r) + } else { + for (n = d/8, i = 0; i <= n; i++) { + extract_byte(xi, xp, i, xo); + extract_byte(yi, yp, i, yo); + if (i == n) { + if ((j = d%8) == 0) + break; + extract_byte(ri, rp, n, ro); + set_high(ri, j, (*op)(xi, yi)); + } else + ri = (*op)(xi, yi); + store_byte(rp, i, ro, ri); + } + if (!replace) + @(return r) + } + rp = r0->vector.self.bit; + ro = r0->vector.offset; + for (n = d/8, i = 0; i <= n; i++) { + if (i == n) { + if ((j = d%8) == 0) + break; + extract_byte(ri, rp, n, ro); + set_high(ri, j, r->vector.self.bit[n]); + } else + ri = r->vector.self.bit[i]; + store_byte(rp, i, ro, ri); + } + @(return r0) +ERROR: + FEerror("Illegal arguments for bit-array operation.", 0); +@) + diff --git a/src/c/num_pred.d b/src/c/num_pred.d new file mode 100644 index 000000000..bfef4b954 --- /dev/null +++ b/src/c/num_pred.d @@ -0,0 +1,148 @@ +/* + num_pred.c -- Predicates on numbers. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +int +number_zerop(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + return(x == MAKE_FIXNUM(0)); + + case t_bignum: + case t_ratio: + return(0); + + case t_shortfloat: + return(sf(x) == 0.0); + + case t_longfloat: + return(lf(x) == 0.0); + + case t_complex: + return(number_zerop(x->complex.real) && + number_zerop(x->complex.imag)); + + default: + FEtype_error_number(x); + } +} + +int +number_plusp(cl_object x) +{ + RESTART: + switch (type_of(x)) { + case t_fixnum: + return(fix(x) > 0); + + case t_bignum: + return(big_sign(x) > 0); + + case t_ratio: + /* INV: rat_den is always positive */ + x = x->ratio.num; + goto RESTART; + + case t_shortfloat: + return(sf(x) > 0.0); + + case t_longfloat: + return(lf(x) > 0.0); + + default: + FEtype_error_real(x); + } +} + +int +number_minusp(cl_object x) +{ + RESTART: + switch (type_of(x)) { + case t_fixnum: + return(fix(x) < 0); + + case t_bignum: + return(big_sign(x) < 0); + + case t_ratio: + /* INV: rat_den is always positive */ + x = x->ratio.num; + goto RESTART; + + case t_shortfloat: + return(sf(x) < 0.0); + + case t_longfloat: + return(lf(x) < 0.0); + + default: + FEtype_error_real(x); + } +} + +int +number_oddp(cl_object x) +{ + if (FIXNUMP(x)) + return fix(x) & 1; + if (type_of(x) == t_bignum) + return big_odd_p(x); + FEtype_error_integer(x); +} + +int +number_evenp(cl_object x) +{ + if (FIXNUMP(x)) + return ~fix(x) & 1; + if (type_of(x) == t_bignum) + return big_even_p(x); + FEtype_error_integer(x); +} + +@(defun zerop (x) +@ /* INV: number_zerop() checks type */ + @(return (number_zerop(x) ? Ct : Cnil)) +@) + +@(defun plusp (x) +@ /* INV: number_plusp() checks type */ + @(return (number_plusp(x) ? Ct : Cnil)) +@) + +@(defun minusp (x) +@ /* INV: number_minusp() checks type */ + @(return (number_minusp(x) ? Ct : Cnil)) +@) + +@(defun oddp (x) +@ /* INV: number_oddp() checks type */ + @(return (number_oddp(x) ? Ct : Cnil)) +@) + +@(defun evenp (x) +@ /* INV: number_evenp() checks_type */ + @(return (number_evenp(x) ? Ct : Cnil)) +@) + +/* FIXME: What the hen is this for? */ +@(defun si::nani (x) +@ + @(return (cl_object)fixint(x)) +@) diff --git a/src/c/num_rand.d b/src/c/num_rand.d new file mode 100644 index 000000000..a3d9e7b02 --- /dev/null +++ b/src/c/num_rand.d @@ -0,0 +1,109 @@ +/* + num_rand.c -- Random numbers. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include + +cl_object Vrandom_state; + +static cl_object +rando(cl_object x, cl_object rs) +{ + enum type tx; + cl_object z; + double d; + + tx = type_of(x); + if (number_compare(x, MAKE_FIXNUM(0)) != 1) + FEwrong_type_argument(TSpositive_number, x); + d = (double)(rs->random.value>>1) / (4294967296.0/2.0); + d = number_to_double(x) * d; + if (tx == t_fixnum) { + z = MAKE_FIXNUM((int)d); + return(z); + } else if (tx == t_bignum) { + z = double_to_integer(d); + return(z); + } else if (tx == t_shortfloat) { + z = alloc_object(t_shortfloat); + sf(z) = (float)d; + return(z); + } else if (tx == t_longfloat) { + z = alloc_object(t_longfloat); + lf(z) = d; + return(z); + } else + FEerror("~S is not an integer nor a floating-point number.", + 1, x); +} + +cl_object +make_random_state(cl_object rs) +{ + cl_object z; + + if (Null(rs)) { + z = alloc_object(t_random); + z->random.value = symbol_value(Vrandom_state)->random.value; + return(z); + } else if (rs == Ct) { + z = alloc_object(t_random); + z->random.value = time(0); + return(z); + } else if (type_of(rs) != t_random) + FEwrong_type_argument(Srandom_state, rs); + else { + z =alloc_object(t_random); + z->random.value = rs->random.value; + return(z); + } +} + +static void +advance_random_state(cl_object rs) +{ + rs->random.value + = rs->random.value + + (rs->random.value<<2) + + (rs->random.value<<17) + + (rs->random.value<<27); +} + + +@(defun random (x &optional (rs symbol_value(Vrandom_state))) +@ + if (type_of(rs) != t_random) + FEwrong_type_argument(Srandom_state, rs); + advance_random_state(rs); + @(return rando(x, rs)); +@) + +@(defun make_random_state (&optional (rs Cnil)) +@ + @(return make_random_state(rs)) +@) + +@(defun random_state_p (x) +@ + @(return ((type_of(x) == t_random) ? Ct : Cnil)) +@) + +void +init_num_rand(void) +{ + SYM_VAL(Vrandom_state) = make_random_state(Ct); +} diff --git a/src/c/num_sfun.d b/src/c/num_sfun.d new file mode 100644 index 000000000..9e1b9fa41 --- /dev/null +++ b/src/c/num_sfun.d @@ -0,0 +1,531 @@ +/* + num_sfun.c -- Trascendental functions. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include +#ifndef HAVE_ISOC99 +# define expf exp +# define logf log +# define sqrtf sqrt +# define cosf cos +# define sinf sin +# define tanf tan +# define sinhf sinh +# define coshf cosh +#endif + +#ifndef M_PI +# ifdef PI +# define M_PI PI +# else +# define M_PI 3.14159265358979323846 +# endif +#endif + +cl_object imag_unit, minus_imag_unit, imag_two; + +cl_fixnum +fixnum_expt(cl_fixnum x, cl_fixnum y) +{ + int z; + + z = 1; + while (y > 0) + if (y%2 == 0) { + x *= x; + y /= 2; + } else { + z *= x; + --y; + } + return(z); +} + +cl_object +number_exp(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(expf(number_to_double(x)))); + + case t_shortfloat: + return(make_shortfloat(expf(sf(x)))); + + case t_longfloat: + return(make_longfloat(exp(lf(x)))); + + case t_complex: { + cl_object y, y1; + + y = x->complex.imag; + x = x->complex.real; + x = number_exp(x); + y1 = number_cos(y); + y = number_sin(y); + y = make_complex(y1, y); + x = number_times(x, y); + return(x); + } + + default: + FEtype_error_number(x); + } +} + +cl_object +number_expt(cl_object x, cl_object y) +{ + enum type tx, ty; + cl_object z; + + tx = type_of(x); + ty = type_of(y); + if (ty == t_fixnum && fix(y) == 0) + switch (tx) { + case t_fixnum: case t_bignum: case t_ratio: + return(MAKE_FIXNUM(1)); + + case t_shortfloat: + return(make_shortfloat(1.0)); + + case t_longfloat: + return(make_longfloat(1.0)); + + case t_complex: + z = number_expt(x->complex.real, y); + z = make_complex(z, MAKE_FIXNUM(0)); + return(z); + + default: + FEtype_error_number(x); + } + if (number_zerop(x)) { + if (!number_plusp(ty==t_complex?y->complex.real:y)) + FEerror("Cannot raise zero to the power ~S.", 1, y); + return(number_times(x, y)); + } + if (ty == t_fixnum || ty == t_bignum) { + if (number_minusp(y)) { + z = number_negate(y); + z = number_expt(x, z); + z = number_divide(MAKE_FIXNUM(1), z); + return(z); + } + z = MAKE_FIXNUM(1); + while (number_plusp(y)) + if (number_evenp(y)) { + x = number_times(x, x); + y = integer_divide(y, MAKE_FIXNUM(2)); + } else { + z = number_times(z, x); + y = number_minus(y, MAKE_FIXNUM(1)); + } + return(z); + } + z = number_nlog(x); + z = number_times(z, y); + z = number_exp(z); + return(z); +} + +cl_object +number_nlog(cl_object x) +{ + cl_object r, i, a, p; + + if (type_of(x) == t_complex) { + r = x->complex.real; + i = x->complex.imag; + goto COMPLEX; + } + if (number_zerop(x)) + FEerror("Zero is the logarithmic singularity.", 0); + if (number_minusp(x)) { + r = x; + i = MAKE_FIXNUM(0); + goto COMPLEX; + } + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(logf(number_to_double(x)))); + + case t_shortfloat: + return(make_shortfloat(logf(sf(x)))); + + case t_longfloat: + return(make_longfloat(log(lf(x)))); + + default: + FEtype_error_number(x); + } +COMPLEX: + a = number_times(r, r); + p = number_times(i, i); + a = number_plus(a, p); + a = number_nlog(a); + a = number_divide(a, MAKE_FIXNUM(2)); + p = number_atan2(i, r); + x = make_complex(a, p); + return(x); +} + +cl_object +number_log(cl_object x, cl_object y) +{ + if (number_zerop(y)) + FEerror("Zero is the logarithmic singularity.", 0); + return(number_divide(number_nlog(y), number_nlog(x))); +} + +cl_object +number_sqrt(cl_object x) +{ + cl_object z; + + if (type_of(x) == t_complex) + goto COMPLEX; + if (number_minusp(x)) + goto COMPLEX; + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(sqrtf(number_to_double(x)))); + + case t_shortfloat: + return(make_shortfloat(sqrtf(sf(x)))); + + case t_longfloat: + return(make_longfloat(sqrt(lf(x)))); + + default: + FEtype_error_number(x); + } + +COMPLEX: + z = make_ratio(MAKE_FIXNUM(1), MAKE_FIXNUM(2)); + z = number_expt(x, z); + return(z); +} + +cl_object +number_atan2(cl_object y, cl_object x) +{ + cl_object z; + double dy, dx, dz; + + dy = number_to_double(y); + dx = number_to_double(x); + if (dx > 0.0) + if (dy > 0.0) + dz = atan(dy / dx); + else if (dy == 0.0) + dz = 0.0; + else + dz = -atan(-dy / dx); + else if (dx == 0.0) + if (dy > 0.0) + dz = M_PI / 2.0; + else if (dy == 0.0) + FEerror("Logarithmic singularity.", 0); + else + dz = -M_PI / 2.0; + else + if (dy > 0.0) + dz = M_PI - atan(dy / -dx); + else if (dy == 0.0) + dz = M_PI; + else + dz = -M_PI + atan(-dy / -dx); + if (type_of(x) == t_longfloat || type_of(y) == t_longfloat) + z = make_longfloat(dz); + else + z = make_shortfloat(dz); + return(z); +} + +cl_object +number_atan(cl_object y) +{ + cl_object z, z1; + + if (type_of(y) == t_complex) { +#if 0 /* FIXME! ANSI states it should be this first part */ + z = number_times(imag_unit, y); + z = number_nlog(one_plus(z)) + + number_nlog(number_minus(MAKE_FIXNUM(1), z)); + z = number_divide(z, number_times(MAKE_FIXNUM(2), imag_unit)); +#else + z = number_times(imag_unit, y); + z = one_plus(z); + z1 = number_times(y, y); + z1 = one_plus(z1); + z1 = number_sqrt(z1); + z = number_divide(z, z1); + z = number_nlog(z); + z = number_times(minus_imag_unit, z); +#endif /* ANSI */ + return(z); + } + return(number_atan2(y, MAKE_FIXNUM(1))); +} + +cl_object +number_sin(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(sinf(number_to_double(x)))); + case t_shortfloat: + return(make_shortfloat(sinf(sf(x)))); + case t_longfloat: + return(make_longfloat(sin(lf(x)))); + case t_complex: { + /* + z = x + I y + z = x + I y + sin(z) = sinh(I z) = sinh(-y + I x) + */ + double dx = number_to_double(x->complex.real); + double dy = number_to_double(x->complex.imag); + double a = sin(dx) * cosh(dy); + double b = cos(dx) * sinh(dy); + if (type_of(x->complex.real) != t_longfloat) + return make_complex(make_shortfloat(a), make_shortfloat(b)); + return make_complex(make_longfloat(a), make_longfloat(b)); + } + default: + FEtype_error_number(x); + } +} + +cl_object +number_cos(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(cosf(number_to_double(x)))); + case t_shortfloat: + return(make_shortfloat(cosf(sf(x)))); + case t_longfloat: + return(make_longfloat(cos(lf(x)))); + case t_complex: { + /* + z = x + I y + cos(z) = cosh(I z) = cosh(-y + I x) + */ + double dx = number_to_double(x->complex.real); + double dy = number_to_double(x->complex.imag); + double a = cos(dx) * cosh(dy); + double b = -sin(dx) * sinh(dy); + if (type_of(x->complex.real) != t_longfloat) + return make_complex(make_shortfloat(a), make_shortfloat(b)); + return make_complex(make_longfloat(a), make_longfloat(b)); + } + default: + FEtype_error_number(x); + } +} + +cl_object +number_tan(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(tanf(number_to_double(x)))); + case t_shortfloat: + return(make_shortfloat(tanf(sf(x)))); + case t_longfloat: + return(make_longfloat(tan(lf(x)))); + case t_complex: { + cl_object a = number_sin(x); + cl_object b = number_cos(x); + return number_divide(a, b); + } + default: + FEtype_error_number(x); + } +} + +cl_object +number_sinh(cl_object x) +{ + + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return make_shortfloat(sinhf(number_to_double(x))); + case t_shortfloat: + return make_shortfloat(sinhf(sf(x))); + case t_longfloat: + return make_longfloat(sinh(lf(x))); + case t_complex: { + /* + z = x + I y + sinh(z) = (exp(z)-exp(-z))/2 + = (exp(x)*(cos(y)+Isin(y))-exp(-x)*(cos(y)-Isin(y)))/2 + = sinh(x)*cos(y) + Icosh(x)*sin(y); + */ + double dx = number_to_double(x->complex.real); + double dy = number_to_double(x->complex.imag); + double a = sinh(dx) * cos(dy); + double b = cosh(dx) * sin(dy); + if (type_of(x->complex.real) != t_longfloat) + return make_complex(make_shortfloat(a), make_shortfloat(b)); + return make_complex(make_longfloat(a), make_longfloat(b)); + } + default: + FEtype_error_number(x); + } +} + +cl_object +number_cosh(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return make_shortfloat(coshf(number_to_double(x))); + case t_shortfloat: + return make_shortfloat(coshf(sf(x))); + case t_longfloat: + return make_longfloat(cosh(lf(x))); + case t_complex: { + /* + z = x + I y + cosh(z) = (exp(z)+exp(-z))/2 + = (exp(x)*(cos(y)+Isin(y))+exp(-x)*(cos(y)-Isin(y)))/2 + = cosh(x)*cos(y) + Isinh(x)*sin(y); + */ + double dx = number_to_double(x->complex.real); + double dy = number_to_double(x->complex.imag); + double a = cosh(dx) * cos(dy); + double b = sinh(dx) * sin(dy); + if (type_of(x->complex.real) != t_longfloat) + return make_complex(make_shortfloat(a), make_shortfloat(b)); + return make_complex(make_longfloat(a), make_longfloat(b)); + } + default: + FEtype_error_number(x); + } +} + +cl_object +number_tanh(cl_object x) +{ + switch (type_of(x)) { + case t_fixnum: + case t_bignum: + case t_ratio: + return(make_shortfloat(tanhf(number_to_double(x)))); + case t_shortfloat: + return(make_shortfloat(tanhf(sf(x)))); + case t_longfloat: + return(make_longfloat(tanh(lf(x)))); + case t_complex: { + cl_object a = number_sinh(x); + cl_object b = number_cosh(x); + return number_divide(a, b); + } + default: + FEtype_error_number(x); + } +} + +@(defun exp (x) +@ /* INV: type check in number_exp() */ + @(return number_exp(x)) +@) + +@(defun expt (x y) +@ /* INV: type check in number_expt() */ + @(return number_expt(x, y)) +@) + +@(defun log (x &optional (y OBJNULL)) +@ /* INV: type check in number_nlog() and number_log() */ + if (y == OBJNULL) + @(return number_nlog(x)) + @(return number_log(y, x)) +@) + +@(defun sqrt (x) +@ /* INV: type check in number_sqrt() */ + @(return number_sqrt(x)) +@) + +@(defun sin (x) +@ /* INV: type check in number_sin() */ + @(return number_sin(x)) +@) + +@(defun cos (x) +@ /* INV: type check in number_cos() */ + @(return number_cos(x)) +@) + +@(defun tan (x) +@ /* INV: type check in number_tan() */ + @(return number_tan(x)) +@) + +@(defun atan (x &optional (y OBJNULL)) +@ /* INV: type check in number_atan() & number_atan2() */ + if (y == OBJNULL) + @(return number_atan(x)) + @(return number_atan2(x, y)) +@) + +@(defun sinh (x) +@ /* INV: type check in number_sin() */ + @(return number_sinh(x)) +@) + +@(defun cosh (x) +@ /* INV: type check in number_cos() */ + @(return number_cosh(x)) +@) + +@(defun tanh (x) +@ /* INV: type check in number_tan() */ + @(return number_tanh(x)) +@) + +void +init_num_sfun(void) +{ + imag_unit = make_complex(make_shortfloat(0.0), make_shortfloat(1.0)); + register_root(&imag_unit); + minus_imag_unit = make_complex(make_shortfloat(0.0), + make_shortfloat(-1.0)); + register_root(&minus_imag_unit); + imag_two = make_complex(make_shortfloat(0.0), make_shortfloat(2.0)); + register_root(&imag_two); + + make_constant("PI", make_longfloat(M_PI)); +} diff --git a/src/c/number.d b/src/c/number.d new file mode 100644 index 000000000..2be7bd7e7 --- /dev/null +++ b/src/c/number.d @@ -0,0 +1,207 @@ +/* + number.c -- Numeric constants. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +cl_object shortfloat_zero; +cl_object longfloat_zero; + +int +fixint(cl_object x) +{ + if (!FIXNUMP(x)) + FEwrong_type_argument(Sfixnum, x); + return fix(x); +} + +int +fixnnint(cl_object x) +{ + if (FIXNUMP(x)) { + cl_fixnum i = fix(x); + if (i >= 0) + return i; + } + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Not a non-negative fixnum ~S"), + Kformat_arguments, list(1,x), + Kexpected_type, Sfixnum, Kdatum, x); +} + +cl_object +make_ratio(cl_object num, cl_object den) +{ + cl_object g, r; + + if (number_zerop(num)) + return(MAKE_FIXNUM(0)); + if (number_zerop(den)) + FEerror("Zero denominator.", 0); + if (den == MAKE_FIXNUM(1)) + return(num); + if (number_minusp(den)) { + num = number_negate(num); + den = number_negate(den); + } + g = get_gcd(num, den); + num = integer_divide(num, g); + den = integer_divide(den, g); + if (den == MAKE_FIXNUM(1)) + return num; + if (den == MAKE_FIXNUM(-1)) + return number_negate(num); + r = alloc_object(t_ratio); + r->ratio.num = num; + r->ratio.den = den; + return(r); +} + +cl_object +make_shortfloat(float f) +{ + cl_object x; + + + if (f == (float)0.0) + return(shortfloat_zero); + if (isnanf(f) || isinf(f)) + FEerror("Not a number.",0); + x = alloc_object(t_shortfloat); + sf(x) = f; + return(x); +} + +cl_object +make_longfloat(double f) +{ + cl_object x; + + if (f == (double)0.0) + return(longfloat_zero); + if (isnan(f) || isinf(f)) + FEerror("Not a number.",0); + x = alloc_object(t_longfloat); + lf(x) = f; + return(x); +} + +cl_object +make_complex(cl_object r, cl_object i) +{ + cl_object c; + + switch (type_of(r)) { + case t_fixnum: + case t_bignum: + case t_ratio: + switch (type_of(i)) { + case t_fixnum: + if (i == MAKE_FIXNUM(0)) + return(r); + case t_bignum: + case t_ratio: + break; + case t_shortfloat: + r = make_shortfloat((float)number_to_double(r)); + break; + case t_longfloat: + r = make_longfloat(number_to_double(r)); + break; + default: + FEtype_error_real(i); + } + break; + case t_shortfloat: + switch (type_of(i)) { + case t_fixnum: + case t_bignum: + case t_ratio: + i = make_shortfloat((float)number_to_double(i)); + case t_shortfloat: + break; + case t_longfloat: + r = make_longfloat((double)(sf(r))); + break; + default: + FEtype_error_real(i); + } + break; + case t_longfloat: + switch (type_of(i)) { + case t_fixnum: + case t_bignum: + case t_ratio: + case t_shortfloat: + i = make_longfloat(number_to_double(i)); + case t_longfloat: + break; + default: + FEtype_error_real(i); + } + break; + default: + FEtype_error_real(r); + } + c = alloc_object(t_complex); + c->complex.real = r; + c->complex.imag = i; + return(c); +} + +double +number_to_double(cl_object x) +{ + switch(type_of(x)) { + case t_fixnum: + return((double)(fix(x))); + + case t_bignum: + return(big_to_double(x)); + + case t_ratio: + return(number_to_double(x->ratio.num) / + number_to_double(x->ratio.den)); + + case t_shortfloat: + return((double)(sf(x))); + + case t_longfloat: + return(lf(x)); + + default: + FEtype_error_real(x); + } +} + +void +init_number(void) +{ + shortfloat_zero = alloc_object(t_shortfloat); + sf(shortfloat_zero) = (float)0.0; + longfloat_zero = alloc_object(t_longfloat); + lf(longfloat_zero) = (double)0.0; + register_root(&shortfloat_zero); + register_root(&longfloat_zero); + + make_constant("MOST-POSITIVE-FIXNUM", MAKE_FIXNUM(MOST_POSITIVE_FIX)); + make_constant("MOST-NEGATIVE-FIXNUM", MAKE_FIXNUM(MOST_NEGATIVE_FIX)); + + init_big(); + init_num_co(); + init_num_log(); + init_num_sfun(); + init_num_rand(); +} diff --git a/src/c/old/all_symbols.d b/src/c/old/all_symbols.d new file mode 100644 index 000000000..0f45fe444 --- /dev/null +++ b/src/c/old/all_symbols.d @@ -0,0 +1,308 @@ +#include "ecls.h" +#include "page.h" + +const struct symbol_info all_symbols[] = { +/* assignment.c */ +{&Ssetf, "SETF", CL_ORDINARY}, +{&Spsetf, "PSETF", CL_ORDINARY}, +{&siSsetf_symbol, "SETF-SYMBOL", SI_ORDINARY}, +{&siSclear_compiler_properties, "CLEAR-COMPILER-PROPERTIES", SI_ORDINARY}, +#ifdef PDE +{&siVrecord_source_pathname_p, "*RECORD-SOURCE-PATHNAME-P*", SI_SPECIAL}, +{&siSrecord_source_pathname, "RECORD-SOURCE-PATHNAME", SI_ORDINARY}, +#endif + +/* backq.c */ +{&siScomma, ",", SI_ORDINARY}, +{&siScomma_at, ",@@", SI_ORDINARY}, +{&siScomma_dot, ",.", SI_ORDINARY}, +{&SlistX, "LIST*", CL_ORDINARY}, +{&Sappend, "APPEND", CL_ORDINARY}, +{&Snconc, "NCONC", CL_ORDINARY}, + +/* bind.c */ +{&SAoptional, "&OPTIONAL", CL_ORDINARY}, +{&SArest, "&REST", CL_ORDINARY}, +{&SAkey, "&KEY", CL_ORDINARY}, +{&SAallow_other_keys, "&ALLOW-OTHER-KEYS", CL_ORDINARY}, +{&SAaux, "&AUX", CL_ORDINARY}, + +/* block.c */ +{&Sblock, "BLOCK", CL_ORDINARY}, + +/* clos.c */ +#ifdef CLOS +{&siSXclass_name_hash_tableX, "*CLASS-NAME-HASH-TABLE*", SI_SPECIAL}, +{&Sclass, "CLASS", CL_ORDINARY}, +{&Sbuilt_in, "BUILT-IN", CL_ORDINARY}, +#endif + +/* compiler.c */ +{&siSlambda_block, "LAMBDA-BLOCK", CL_ORDINARY}, + +/* conditional.c */ +{&Sotherwise, "OTHERWISE", CL_ORDINARY}, + +/* error.c */ +{&siSuniversal_error_handler, "UNIVERSAL-ERROR-HANDLER", SI_ORDINARY}, +{&siSterminal_interrupt, "TERMINAL-INTERRUPT", SI_ORDINARY}, + +/* eval.c */ +{&Sapply, "APPLY", CL_ORDINARY}, +{&Sfuncall, "FUNCALL", CL_ORDINARY}, +{&Vevalhook, "*EVALHOOK*", CL_SPECIAL}, +{&Vapplyhook, "*APPLYHOOK*", CL_SPECIAL}, + +/* file.c */ +{&Vstandard_input, "*STANDARD-INPUT*", CL_SPECIAL}, +{&Vstandard_output, "*STANDARD-OUTPUT*", CL_SPECIAL}, +{&Verror_output, "*ERROR-OUTPUT*", CL_SPECIAL}, +{&Vquery_io, "*QUERY-IO*", CL_SPECIAL}, +{&Vdebug_io, "*DEBUG-IO*", CL_SPECIAL}, +{&Vterminal_io, "*TERMINAL-IO*", CL_SPECIAL}, +{&Vtrace_output, "*TRACE-OUTPUT*", CL_SPECIAL}, +{&siVignore_eof_on_terminal_io, "*IGNORE-EOF-ON-TERMINAL-IO*", SI_SPECIAL}, + +/* format.c */ +{&siVindent_formatted_output, "*INDENT-FORMATTED-OUTPUT*", SI_SPECIAL}, + +/* gbc.c */ +#if 0 && !defined(GBC_BOEHM) +{&siVgc_verbose, "*GC-VERBOSE*", SI_SPECIAL}, +{&siVgc_message, "*GC-MESSAGE*", SI_SPECIAL}, +#endif /* !GBC_BOEHM */ + +/* gfun.c */ +{&siScompute_applicable_methods, "COMPUTE-APPLICABLE-METHODS", SI_ORDINARY}, +{&siScompute_effective_method, "COMPUTE-EFFECTIVE-METHOD", SI_ORDINARY}, +{&siSgeneric_function_method_combination, "GENERIC-FUNCTION-METHOD-COMBINATION", SI_ORDINARY}, +{&siSgeneric_function_method_combination_args, "GENERIC-FUNCTION-METHOD-COMBINATION-ARGS", SI_ORDINARY}, + +/* hash.c */ +{&Seq, "EQ", CL_ORDINARY}, +{&Seql, "EQL", CL_ORDINARY}, +{&Sequal, "EQUAL", CL_ORDINARY}, + +/* instance.c */ +{&Sprint_object, "PRINT-OBJECT", CL_ORDINARY}, + +/* lex.c */ +{&Smacro, "MACRO", CL_ORDINARY}, +{&siSsymbol_macro, "SYMBOL-MACRO", SI_ORDINARY}, +{&Stag, "TAG", CL_ORDINARY}, + +/* load.c */ +{&Vload_verbose, "*LOAD-VERBOSE*", CL_SPECIAL}, +#ifdef PDE +{&siVsource_pathname, "*SOURCE-PATHNAME*", CL_SPECIAL}, +#endif +#ifdef RSYM +{&siVsymbol_table, "*SYMBOL-TABLE*", CL_SPECIAL}, +#endif + +/* lwp.c */ +#ifdef THREADS +{&Srunning, "RUNNING", CL_ORDINARY}, +{&Ssuspended, "SUSPENDED", CL_ORDINARY}, +{&Swaiting, "WAITING", CL_ORDINARY}, +{&Sstopped, "STOPPED", CL_ORDINARY}, +{&Sdead, "DEAD", CL_ORDINARY}, +{&siSthread_top_level, "THREAD-TOP-LEVEL", SI_ORDINARY}, +#endif + +/* macros.c */ +{&Vmacroexpand_hook, "*MACROEXPAND-HOOK*", CL_SPECIAL}, +{&siSexpand_defmacro, "EXPAND-DEFMACRO", SI_ORDINARY}, +{&siVinhibit_macro_special, "*INHIBIT-MACRO-SPECIAL*", SI_SPECIAL}, + +/* main.c */ +{&siVsystem_directory, "*SYSTEM-DIRECTORY*", SI_SPECIAL}, +{&Vfeatures, "*FEATURES*", CL_SPECIAL}, + +/* num_rand.c */ +{&Vrandom_state, "*RANDOM-STATE*", CL_SPECIAL}, + +/* package.c */ +{&Vpackage, "*PACKAGE*", CL_SPECIAL}, + +/* pathname.c */ +{&Vdefault_pathname_defaults, "*DEFAULT-PATHNAME-DEFAULTS*", CL_SPECIAL}, + +/* print.c */ +{&Vprint_escape, "*PRINT-ESCAPE*", CL_SPECIAL}, +{&Vprint_pretty, "*PRINT-PRETTY*", CL_SPECIAL}, +{&Vprint_circle, "*PRINT-CIRCLE*", CL_SPECIAL}, +{&Vprint_base, "*PRINT-BASE*", CL_SPECIAL}, +{&Vprint_radix, "*PRINT-RADIX*", CL_SPECIAL}, +{&Vprint_case, "*PRINT-CASE*", CL_SPECIAL}, +{&Vprint_gensym, "*PRINT-GENSYM*", CL_SPECIAL}, +{&Vprint_level, "*PRINT-LEVEL*", CL_SPECIAL}, +{&Vprint_length, "*PRINT-LENGTH*", CL_SPECIAL}, +{&Vprint_array, "*PRINT-ARRAY*", CL_SPECIAL}, +{&siSpretty_print_format, "PRETTY-PRINT-FORMAT", SI_ORDINARY}, +{&siSsharp_exclamation, "#!", SI_ORDINARY}, +{&siVprint_package, "*PRINT-PACKAGE*", SI_SPECIAL}, +{&siVprint_structure, "*PRINT-STRUCTURE*", SI_SPECIAL}, +#ifdef CLOS +{&Sstream_write_char, "STREAM-WRITE-CHAR", CL_ORDINARY}, +{&Sstream_write_string, "STREAM-WRITE-STRING", CL_ORDINARY}, +{&Sstream_fresh_line, "STREAM-FRESH-LINE", CL_ORDINARY}, +{&Sstream_clear_output, "STREAM-CLEAR-OUTPUT", CL_ORDINARY}, +{&Sstream_force_output, "STREAM-FORCE-OUTPUT", CL_ORDINARY}, +#endif + +/* profile.c */ +#ifdef PROFILE +{&sSAprofile_arrayA, "*PROFILE-ARRAY*", SI_SPECIAL}, +#endif PROFILE + +/* read.c */ +{&Vreadtable, "*READTABLE*", CL_SPECIAL}, +{&Vread_default_float_format, "*READ-DEFAULT-FLOAT-FORMAT*", CL_SPECIAL}, +{&Vread_base, "*READ-BASE*", CL_SPECIAL}, +{&Vread_suppress, "*READ-SUPPRESS*", CL_SPECIAL}, +{&siSsharp_comma, "#,", SI_ORDINARY}, +#ifdef CLOS +{&Sstream_read_line, "STREAM-READ-LINE", CL_ORDINARY}, +{&Sstream_read_char, "STREAM-READ-CHAR", CL_ORDINARY}, +{&Sstream_unread_char, "STREAM-UNREAD-CHAR", CL_ORDINARY}, +{&Sstream_peek_char, "STREAM-PEEK-CHAR", CL_ORDINARY}, +{&Sstream_listen, "STREAM-LISTEN", CL_ORDINARY}, +{&Sstream_clear_input, "STREAM-CLEAR-INPUT", CL_ORDINARY}, +#endif + +/* structure.c */ +{&siSstructure_print_function, "STRUCTURE-PRINT-FUNCTION", SI_ORDINARY}, +{&siSstructure_slot_descriptions, "STRUCTURE-SLOT-DESCRIPTIONS", SI_ORDINARY}, +#ifndef CLOS +{&siSstructure_include, "STRUCTURE-INCLUDE", SI_ORDINARY}, +#else +{&Sstructure_object, "STRUCTURE-OBJECT", CL_ORDINARY}, +#endif + +/* symbol.c */ +{&siSpname, "PNAME", SI_ORDINARY}, +{&Vgensym_counter, "*GENSYM-COUNTER*", CL_SPECIAL}, + +/* toplevel.c */ +{&Sdeclare, "DECLARE", CL_ORDINARY}, +{&Scompile, "COMPILE", CL_ORDINARY}, +{&Sload, "LOAD", CL_ORDINARY}, +{&Seval, "EVAL", CL_ORDINARY}, +{&Sprogn, "PROGN", CL_ORDINARY}, +{&Swarn, "WARN", CL_ORDINARY}, +{&Stypep, "TYPEP", CL_ORDINARY}, + +/* typespec.c */ +{&Squote, "QUOTE", CL_ORDINARY}, +{&Slambda, "LAMBDA", CL_ORDINARY}, +{&Sspecial, "SPECIAL", CL_ORDINARY}, +{&St, "T", CL_ORDINARY}, +{&Snil, "NIL", CL_ORDINARY}, +{&Scommon, "COMMON", CL_ORDINARY}, +{&Ssequence, "SEQUENCE", CL_ORDINARY}, +{&Snull, "NULL", CL_ORDINARY}, +{&Scons, "CONS", CL_ORDINARY}, +{&Slist, "LIST", CL_ORDINARY}, +{&Ssymbol, "SYMBOL", CL_ORDINARY}, +{&Sarray, "ARRAY", CL_ORDINARY}, +{&Svector, "VECTOR", CL_ORDINARY}, +{&Sbit_vector, "BIT-VECTOR", CL_ORDINARY}, +{&Sstring, "STRING", CL_ORDINARY}, +{&Ssimple_array, "SIMPLE-ARRAY", CL_ORDINARY}, +{&Ssimple_vector, "SIMPLE-VECTOR", CL_ORDINARY}, +{&Ssimple_string, "SIMPLE-STRING", CL_ORDINARY}, +{&Ssimple_bit_vector, "SIMPLE-BIT-VECTOR", CL_ORDINARY}, +{&Sfunction, "FUNCTION", CL_ORDINARY}, +{&Spathname, "PATHNAME", CL_ORDINARY}, +{&Slogical_pathname, "LOGICAL-PATHNAME", CL_ORDINARY}, +{&Scharacter, "CHARACTER", CL_ORDINARY}, +{&Sbase_char, "BASE-CHAR", CL_ORDINARY}, +{&Sextended_char, "EXTENDED-CHAR", CL_ORDINARY}, +{&Scompiled_function, "COMPILED-FUNCTION", CL_ORDINARY}, +{&Snumber, "NUMBER", CL_ORDINARY}, +{&Sreal, "REAL", CL_ORDINARY}, +{&Srational, "RATIONAL", CL_ORDINARY}, +{&Sfloat, "FLOAT", CL_ORDINARY}, +{&Sinteger, "INTEGER", CL_ORDINARY}, +{&Sratio, "RATIO", CL_ORDINARY}, +{&Sshort_float, "SHORT-FLOAT", CL_ORDINARY}, +{&Sstandard_char, "STANDARD-CHAR", CL_ORDINARY}, +{&Sfixnum, "FIXNUM", CL_ORDINARY}, +{&Scomplex, "COMPLEX", CL_ORDINARY}, +{&Ssingle_float, "SINGLE-FLOAT", CL_ORDINARY}, +{&Spackage, "PACKAGE", CL_ORDINARY}, +{&Sbignum, "BIGNUM", CL_ORDINARY}, +{&Srandom_state, "RANDOM-STATE", CL_ORDINARY}, +{&Sdouble_float, "DOUBLE-FLOAT", CL_ORDINARY}, +{&Sstream, "STREAM", CL_ORDINARY}, +{&Sbit, "BIT", CL_ORDINARY}, +{&Sreadtable, "READTABLE", CL_ORDINARY}, +{&Slong_float, "LONG-FLOAT", CL_ORDINARY}, +{&Shash_table, "HASH-TABLE", CL_ORDINARY}, +{&Ssigned_char, "SIGNED-CHAR", CL_ORDINARY}, +{&Sunsigned_char, "UNSIGNED-CHAR", CL_ORDINARY}, +{&Ssigned_short, "SIGNED-SHORT", CL_ORDINARY}, +{&Sunsigned_short, "UNSIGNED-SHORT", CL_ORDINARY}, +#ifdef CLOS +{&Sinstance, "INSTANCE", CL_ORDINARY}, +{&Sdispatch_function, "DISPATCH-FUNCTION", CL_ORDINARY}, +{&Sstructure, "STRUCTURE", CL_ORDINARY}, +#endif +{&Ssatisfies, "SATISFIES", CL_ORDINARY}, +{&Smember, "MEMBER", CL_ORDINARY}, +{&Snot, "NOT", CL_ORDINARY}, +{&Sor, "OR", CL_ORDINARY}, +{&Sand, "AND", CL_ORDINARY}, +{&Svalues, "VALUES", CL_ORDINARY}, +{&Smod, "MOD", CL_ORDINARY}, +{&Ssigned_byte, "SIGNED-BYTE", CL_ORDINARY}, +{&Sunsigned_byte, "UNSIGNED-BYTE", CL_ORDINARY}, +{&SX, "*", CL_ORDINARY}, +{&Splusp, "PLUSP", CL_ORDINARY}, +{&Skeyword, "KEYWORD", CL_ORDINARY}, +#ifdef THREADS +{&Scont, "CONT", CL_ORDINARY}, +{&Sthread, "THREAD", CL_ORDINARY}, +#endif +#ifdef LOCATIVE +{&Slocative, "LOCATIVE", CL_ORDINARY}, +#endif +{&Ssubtypep, "SUBTYPEP", CL_ORDINARY}, + +/* unify.c */ +#ifdef LOCATIVE +{&Ssetq, "SETQ", CL_ORDINARY}, +{&Sunify_slot, "UNIFY-SLOT", CL_ORDINARY}, +#endif + +{NULL, (const char*)NULL, CL_ORDINARY}}; + +void +init_all_symbols(void) { + const struct symbol_info *s = all_symbols; + cl_object *loc; + + /* This must keep the garbage collector happy */ + for (s = all_symbols; s->name != NULL; s++) + *(s->loc) = OBJNULL; + + for (s = all_symbols; s->name != NULL; s++) { + loc = s->loc; + switch (s->type) { + case CL_ORDINARY: + *loc = make_ordinary(s->name); + break; + case CL_SPECIAL: + *loc = make_special(s->name, Cnil); + break; + case SI_ORDINARY: + *loc = make_si_ordinary(s->name); + break; + case SI_SPECIAL: + *loc = make_si_special(s->name, Cnil); + break; + } + /* register_root(loc);*/ + } +} diff --git a/src/c/old/compiler.d b/src/c/old/compiler.d new file mode 100644 index 000000000..9cbae7526 --- /dev/null +++ b/src/c/old/compiler.d @@ -0,0 +1,2148 @@ +/* + compiler.c -- Bytecode compiler +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +/********************* EXPORTS *********************/ + +cl_object siSlambda_block; +cl_object Sdeclare; +cl_object Sdefun; +cl_object Scompile, Sload, Seval, Sprogn, Swarn, Stypep, Sotherwise; +cl_object Kexecute, Kcompile_toplevel, Kload_toplevel; +cl_object siVinhibit_macro_special; + +cl_object SAoptional; +cl_object SArest; +cl_object SAkey; +cl_object SAallow_other_keys; +cl_object SAaux; + +cl_object Kallow_other_keys; + +cl_object bytecodes; + +/********************* PRIVATE ********************/ + +static cl_index asm_begin(void); +static cl_object asm_end(cl_index); +static void asm_clear(cl_index); +static void asm_grow(void); +static void asm1(register cl_object op); +static void asm_op(register int n); +static void asm_list(register cl_object l); +static void asmn(int narg, ...); +static void asm_at(register cl_index where, register cl_object what); +static cl_index asm_jmp(register int op); +static void asm_complete(register int op, register cl_index original); +static cl_index current_pc(); +static void set_pc(cl_index pc); +static cl_object asm_ref(register cl_index where); + +static void c_and(cl_object args); +static void c_block(cl_object args); +static void c_case(cl_object args); +static void c_catch(cl_object args); +static void c_cond(cl_object args); +static void c_do(cl_object args); +static void c_doa(cl_object args); +static void c_dolist(cl_object args); +static void c_dotimes(cl_object args); +static void c_eval_when(cl_object args); +static void c_flet(cl_object args); +static void c_function(cl_object args); +static void c_go(cl_object args); +static void c_if(cl_object args); +static void c_labels(cl_object args); +static void c_let(cl_object args); +static void c_leta(cl_object args); +static void c_macrolet(cl_object args); +static void c_multiple_value_bind(cl_object args); +static void c_multiple_value_call(cl_object args); +static void c_multiple_value_prog1(cl_object args); +static void c_multiple_value_setq(cl_object args); +static void c_nth_value(cl_object args); +static void c_or(cl_object args); +static void c_progv(cl_object args); +static void c_psetq(cl_object args); +static void c_values(cl_object args); +static void c_setq(cl_object args); +static void c_return(cl_object args); +static void c_return_from(cl_object args); +static void c_symbol_macrolet(cl_object args); +static void c_tagbody(cl_object args); +static void c_throw(cl_object args); +static void c_unless(cl_object args); +static void c_unwind_protect(cl_object args); +static void c_when(cl_object args); +static void compile_body(cl_object args); +static void compile_form(cl_object args, bool push); + +/* -------------------- SAFE LIST HANDLING -------------------- */ + +static cl_object +pop(cl_object *l) { + cl_object head, list = *l; + if (ATOM(list)) + FEerror("Error parsing special form",0); + head = CAR(list); + *l = CDR(list); + return head; +} + +static cl_object +pop_maybe_nil(cl_object *l) { + cl_object head, list = *l; + if (list == Cnil) + return Cnil; + if (ATOM(list)) + FEerror("Error parsing special form",0); + head = CAR(list); + *l = CDR(list); + return head; +} + +/* ------------------------------ ASSEMBLER ------------------------------ */ + +static cl_index +asm_begin(void) { + /* Save beginning of bytecodes for this session */ + return current_pc(); +} + +static void +asm_clear(cl_index beginning) { + cl_index i; + /* Remove data from this session */ + bytecodes->vector.fillp = beginning; +} + +static cl_object +asm_end(cl_index beginning) { + cl_object new_bytecodes; + cl_index length, bytes, i; + + /* Save bytecodes from this session in a new vector */ + length = current_pc() - beginning; + bytes = length * sizeof(cl_object); + new_bytecodes = alloc_object(t_bytecodes); + new_bytecodes->bytecodes.lex = Cnil; + new_bytecodes->bytecodes.data = alloc(bytes); + new_bytecodes->bytecodes.size = length; + memcpy(new_bytecodes->bytecodes.data, + &bytecodes->vector.self.t[beginning], + bytes); + + asm_clear(beginning); + return new_bytecodes; +} + +static void +asm_grow(void) { + cl_object *old_data = bytecodes->vector.self.t; + cl_index old_size = bytecodes->vector.fillp; + bytecodes->vector.dim += 128; + array_allocself(bytecodes); + memcpy(bytecodes->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +asm1(register cl_object op) { + int where = bytecodes->vector.fillp; + if (where >= bytecodes->vector.dim) + asm_grow(); + bytecodes->vector.self.t[where] = op; + bytecodes->vector.fillp++; +} + +static void +asm_op(register int n) { + asm1(MAKE_FIXNUM(n)); +} + +static void +asm_op2(register int code, register cl_fixnum n) { + cl_object op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEerror("Argument to bytecode is too large", 0); + else + asm1(new_op); +} + +static inline cl_object +make_op(int code) { + return MAKE_FIXNUM(code); +} + +static cl_object +make_op2(int code, cl_fixnum n) { + cl_object volatile op = MAKE_FIXNUM(code); + cl_object new_op = SET_OPARG(op, n); + if (n < -MAX_OPARG || MAX_OPARG < n) + FEerror("Argument to bytecode is too large", 0); + return new_op; +} + +static void +asm_insert(cl_fixnum where, cl_object op) { + cl_fixnum end = bytecodes->vector.fillp; + if (where > end) + FEerror("asm1_insert: position out of range", 0); + if (end >= bytecodes->vector.dim) + asm_grow(); + memmove(&bytecodes->vector.self.t[where+1], + &bytecodes->vector.self.t[where], + (end - where) * sizeof(cl_object)); + bytecodes->vector.fillp++; + bytecodes->vector.self.t[where] = op; +} + +static void +asm_list(register cl_object l) { + if (ATOM(l)) + asm1(l); + while(!endp(l)) { + asm1(CAR(l)); + l = CDR(l); + } +} + +static void +asmn(int narg, ...) { + va_list args; + + va_start(args, narg); + while (narg-- > 0) + asm1(va_arg(args, cl_object)); +} + +static void +asm_at(register cl_index where, register cl_object what) { + if (where > bytecodes->vector.fillp) + FEerror("Internal error at asm_at()",0); + bytecodes->vector.self.t[where] = what; +} + +static cl_index +asm_block(void) { + cl_index output; + output = current_pc(); + asm1(MAKE_FIXNUM(0)); + return output; +} + +static cl_index +asm_jmp(register int op) { + cl_index output = current_pc(); + asm_op(op); + return output; +} + +static void +asm_complete(register int op, register cl_index original) { + cl_fixnum delta = current_pc() - original; + cl_object code = asm_ref(original); + cl_object new_code = SET_OPARG(code, delta); + if (code != MAKE_FIXNUM(op)) + FEerror("Non matching codes in ASM-COMPLETE2", 0); + else if (delta < -MAX_OPARG || delta > MAX_OPARG) + FEerror("Too large jump", 0); + else + asm_at(original, new_code); +} + +static cl_index +current_pc(void) { + return bytecodes->vector.fillp; +} + +static void +set_pc(cl_index pc) { + bytecodes->vector.fillp = pc; +} + +static cl_object +asm_ref(register cl_index n) { + return bytecodes->vector.self.t[n]; +} + +/* ------------------------------ COMPILER ------------------------------ */ + +typedef struct { + cl_object symbol; + const char *const name; + void (*compiler)(cl_object); +} compiler_record; + +static compiler_record database[] = { + {OBJNULL, "AND", c_and}, + {OBJNULL, "BLOCK", c_block}, + {OBJNULL, "CASE", c_case}, + {OBJNULL, "CATCH", c_catch}, + {OBJNULL, "COND", c_cond}, + {OBJNULL, "DO", c_do}, + {OBJNULL, "DO*", c_doa}, + {OBJNULL, "DOLIST", c_dolist}, + {OBJNULL, "DOTIMES", c_dotimes}, + {OBJNULL, "EVAL-WHEN", c_eval_when}, + {OBJNULL, "FLET", c_flet}, + {OBJNULL, "FUNCTION", c_function}, + {OBJNULL, "GO", c_go}, + {OBJNULL, "IF", c_if}, + {OBJNULL, "LABELS", c_labels}, + {OBJNULL, "LET", c_let}, + {OBJNULL, "LET*", c_leta}, + {OBJNULL, "MACROLET", c_macrolet}, + {OBJNULL, "MULTIPLE-VALUE-BIND", c_multiple_value_bind}, + {OBJNULL, "MULTIPLE-VALUE-CALL", c_multiple_value_call}, + {OBJNULL, "MULTIPLE-VALUE-PROG1", c_multiple_value_prog1}, + {OBJNULL, "MULTIPLE-VALUE-SETQ", c_multiple_value_setq}, + {OBJNULL, "NTH-VALUE", c_nth_value}, + {OBJNULL, "OR", c_or}, + {OBJNULL, "PROGN", compile_body}, + {OBJNULL, "PROGV", c_progv}, + {OBJNULL, "PSETQ", c_psetq}, + {OBJNULL, "RETURN", c_return}, + {OBJNULL, "RETURN-FROM", c_return_from}, + {OBJNULL, "SETQ", c_setq}, + {OBJNULL, "TAGBODY", c_tagbody}, + {OBJNULL, "THROW", c_throw}, + {OBJNULL, "UNWIND-PROTECT", c_unwind_protect}, + {OBJNULL, "UNLESS", c_unless}, + {OBJNULL, "VALUES", c_values}, + {OBJNULL, "WHEN", c_when}, + {OBJNULL, "", c_when} +}; + +/* ----------------- LEXICAL ENVIRONMENT HANDLING -------------------- */ + +static void +c_register_var(register cl_object var, bool special) +{ + CAR(lex_env) = CONS(CONS(var, special? Sspecial : Cnil), CAR(lex_env)); +} + +static bool +special_variablep(register cl_object var, register cl_object specials) +{ + return ((var->symbol.stype == stp_special) || member_eq(var, specials)); +} + +static void +c_pbind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEerror("The object ~A is not a valid variable name", 1, var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_PBINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_PBIND); + } + asm1(var); +} + +static void +c_bind(cl_object var, cl_object specials) +{ + if (!SYMBOLP(var)) + FEerror("The object ~A is not a valid variable name", 1, var); + else if (special_variablep(var, specials)) { + c_register_var(var, TRUE); + asm_op(OP_BINDS); + } else { + c_register_var(var, FALSE); + asm_op(OP_BIND); + } + asm1(var); +} + +static void +compile_setq(int op, cl_object var) +{ + cl_object ndx; + + if (!SYMBOLP(var)) + FEerror("SETQ: ~A is not a symbol", 1, var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm_op(op); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEerror("SETQ: Cannot change the value of the constant ~A", 1,var); + else if (op == OP_SETQ) + asm_op(OP_SETQS); /* Special variable */ + else + asm_op(OP_PSETQS); /* Special variable */ + asm1(var); +} + +static void +bind_tag(cl_object tag) +{ + CDR(lex_env) = CONS(list(3, tag, Stag, Cnil), CDR(lex_env)); +} + +static bool +reference_tag(cl_object tag) +{ + cl_object l; + bool non_local = FALSE; + + for (l = CDR(lex_env); !endp(l); l = CDR(l)) { + cl_object record = CAR(l); + if (ATOM(record)) + non_local = TRUE; + else if (CAR(record) == Ct && CDR(record) == Cnil) + non_local = TRUE; + else if (eql(CAR(record), tag) && CADR(record) == Stag) { + cl_object mark; + if (non_local) + mark = Ct; + else + mark = MAKE_FIXNUM(current_pc()); + CADDR(record) = nconc(CADDR(record), CONS(mark, Cnil)); + return non_local; + } + } + FEerror("Reference to unknown tag ~S", 1, tag); +} + +/* -------------------- THE COMPILER -------------------- */ + +static void +c_and(cl_object args) { + if (Null(args)) { + asm1(Ct); + return; + } else if (ATOM(args)) { + FEerror("Wrong type of argument to AND ~S", 1, args); + } else { + compile_form(pop(&args),FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JNIL); + c_and(args); + asm_complete(OP_JNIL, label); + } + } +} + +/* + The OP_BLOCK operator encloses several forms within a block + named BLOCK_NAME, thus catching any OP_RETFROM whose argument + matches BLOCK_NAME. The end of this block is marked both by + the OP_EXIT operator and the LABELZ which is packed within + the OP_BLOCK operator. + + [OP_BLOCK + labelz] + block_name + .... + OP_EXIT + labelz: ... +*/ + +static void +c_block(cl_object body) { + cl_object name = pop(&body); + cl_index labelz = asm_jmp(OP_BLOCK); + if (!SYMBOLP(name)) + FEerror("Not a valid BLOCK name: ~S", 1, name); + asm1(name); + compile_body(body); + asm_op(OP_EXIT); + asm_complete(OP_BLOCK, labelz); +} + +/* + There are several ways to invoke functions and to handle the + output arguments. These are + + [OP_CALL + nargs] + function_name + + [OP_PCALL + nargs] + function_name + + [OP_FCALL + nargs] + + [OP_PFCALL + nargs] + + OP_CALL and OP_FCALL leave all arguments in the VALUES() array, + while OP_PCALL and OP_PFCALL leave the first argument in the + stack. + + OP_CALL and OP_PCALL use the following symbol to retrieve the + function, while OP_FCALL and OP_PFCALL use the value in VALUES(0). + */ +static void +c_call(cl_object args, bool push) { + cl_object name; + cl_index nargs; + + name = pop(&args); + for (nargs = 0; !endp(args); nargs++) { + compile_form(pop(&args),TRUE); + } + if (ATOM(name)) { + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(name); + } else if (CAR(name) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(name))); + asm_op2(push? OP_PFCALL : OP_FCALL, nargs); + } else { + cl_object aux = setf_namep(name); + if (aux == OBJNULL) + FEerror("Invalid function name ~S", 1, name); + asm_op2(push? OP_PCALL : OP_CALL, nargs); + asm1(aux); + } +} + +static void +perform_c_case(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label1, label2; + + if (Null(args)) { + asm_op(OP_NOP); + return; + } + + clause = pop(&args); + if (ATOM(clause)) + FEerror("~S is an illegal CASE clause.",1,clause); + test = pop(&clause); + if (Sotherwise == test || test == Ct) { + compile_body(clause); + } else { + cl_index labeln, labelz; + if (CONSP(test)) { + cl_index n = length(test); + while (n > 1) { + cl_object v = pop(&test); + cl_fixnum jump = (n--) * 2; + asm_op2(OP_JEQ, jump); + asm1(v); + } + test = CAR(test); + } + labeln = asm_jmp(OP_JNEQ); + asm1(test); + compile_body(clause); + labelz = asm_jmp(OP_JMP); + asm_complete(OP_JNEQ, labeln); + perform_c_case(args); + asm_complete(OP_JMP, labelz); + } +} + +static void +c_case(cl_object clause) { + compile_form(pop(&clause), FALSE); + perform_c_case(clause); +} + +/* + The OP_CATCH takes the object in VALUES(0) and uses it to catch + any OP_THROW operation which uses that value as argument. If a + catch occurs, or when all forms have been properly executed, it + jumps to LABELZ. LABELZ is packed within the OP_CATCH operator. + [OP_CATCH + labelz] + ... + "forms to be caught" + ... + OP_EXIT + labelz: ... +*/ + +static void +c_catch(cl_object args) { + cl_index labelz; + + /* Compile evaluation of tag */ + compile_form(pop(&args), FALSE); + + /* Compile jump point */ + labelz = asm_jmp(OP_CATCH); + + /* Compile body of CATCH */ + compile_body(args); + asm_op(OP_EXIT); + asm_complete(OP_CATCH, labelz); +} + +/* + There are three operators which perform explicit jumps, but + almost all other operators use labels in one way or + another. + + 1) Jumps are always relative to the place where the jump label + is retrieved so that if the label is in vector[0], then the + destination is roughly vector + vector[0]. + + 2) There are two types of labels, "packed labels" and "simple + labels". The first ones are packed in the upper bits of an + operator so that + destination = vector + vector[0]>>16 + Simple labels take the whole word and thus + destination = vector + fix(vector[0]) + + 3) The three jump forms are + + [OP_JMP + label] ; Unconditional jump + [OP_JNIL + label] ; Jump if VALUES(0) == Cnil + [OP_JT + label] ; Jump if VALUES(0) != Cnil + + It is important to remark that both OP_JNIL and OP_JT truncate + the values stack, so that always NValues = 1 after performing + any of these operations. +*/ +static void +c_cond(cl_object args) { + cl_object test, clause, conseq; + cl_fixnum label_nil, label_exit; + + clause = pop(&args); + if (ATOM(clause)) + FEerror("~S is an illegal COND clause.",1,clause); + test = pop(&clause); + if (Ct == test) { + /* Default sentence. If no forms, just output T. */ + if (Null(clause)) + compile_form(Ct, FALSE); + else + compile_body(clause); + } else { + /* Compile the test. If no more forms, just output + the first value (this is guaranteed by OP_JNIL */ + compile_form(test, FALSE); + label_nil = asm_jmp(OP_JNIL); + if (!Null(clause)) + compile_body(clause); + if (Null(args)) + asm_complete(OP_JNIL, label_nil); + else { + label_exit = asm_jmp(OP_JMP); + asm_complete(OP_JNIL, label_nil); + c_cond(args); + asm_complete(OP_JMP, label_exit); + } + } +} + +/* The OP_DO operator saves the lexical environment and establishes + a NIL block to execute the enclosed forms, which are typically + like the ones shown below. At the exit of the block, either by + means of a OP_RETFROM jump or because of normal termination, + the lexical environment is restored, and all bindings undone. + + [OP_DO + labelz] + labelz + ... ; bindings + labelb: ... ; body + ... ; stepping forms + labelt: ... ; test form + [JNIL + label] + ... ; output form + OP_EXIT + labelz: + +*/ +static void +c_do_doa(int op, cl_object args) { + cl_object bindings, test, specials, body, l; + cl_object stepping = Cnil, vars = Cnil; + cl_index labelb, labelt, labelz; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = pop(&args); + test = pop(&args); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + labelz = asm_jmp(OP_DO); + + /* Compile initial bindings */ + if (length(bindings) == 1) + op = OP_BIND; + for (l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!endp(aux)) + stepping = CONS(CONS(var,pop(&aux)),stepping); + if (!Null(aux)) + FEerror("Not a valid argument to LET ~S.", 1, + args); + } + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + + /* Jump to test */ + labelt = asm_jmp(OP_JMP); + + /* Compile body */ + labelb = current_pc(); + c_tagbody(body); + + /* Compile stepping clauses */ + if (length(stepping) == 1) + op = OP_BIND; + for (vars = Cnil, stepping=nreverse(stepping); !endp(stepping); ) { + cl_object pair = pop(&stepping); + cl_object var = CAR(pair); + cl_object value = CDR(pair); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); + + /* Compile test */ + asm_complete(OP_JMP, labelt); + compile_form(pop(&test), FALSE); + asm_op2(OP_JNIL, labelb - current_pc()); + + /* Compile output clauses */ + compile_body(test); + asm_op(OP_EXIT); + + /* Compile return point of block */ + asm_complete(OP_DO, labelz); + + lex_env = lex_old; +} + + +static void +c_doa(cl_object args) { + c_do_doa(OP_BIND, args); +} + +static void +c_do(cl_object args) { + c_do_doa(OP_PBIND, args); +} + +/* + The OP_DOLIST & OP_DOTIMES operators save the lexical + environment and establishes a NIL block to execute the + enclosed forms, which iterate over the elements in a list or + over a range of integer numbers. At the exit of the block, + either by means of a OP_RETFROM jump or because of normal + termination, the lexical environment is restored, and all + bindings undone. + + [OP_DOTIMES/OP_DOLIST + labelz] + ... ; bindings + [OP_EXIT + labelo] + ... ; body + ... ; stepping forms + OP_EXIT + labelo: ... ; output form + OP_EXIT + labelz: + + */ + +static void +c_dolist_dotimes(int op, cl_object args) { + cl_object head = pop(&args); + cl_object var = pop(&head); + cl_object list = pop(&head); + cl_object specials, body; + cl_index labelz, labelo; + cl_object lex_old = lex_env; + lex_copy(); + + siLprocess_declarations(1, args); + body = VALUES(1); + specials = VALUES(3); + + if (!SYMBOLP(var)) + FEerror("Cannot bind to ~S", 1, var); + + /* Compute list and enter loop */ + compile_form(list, FALSE); + labelz = asm_jmp(op); + + /* Initialize the variable */ + compile_form((op == OP_DOLIST)? Cnil : MAKE_FIXNUM(0), FALSE); + c_bind(var, specials); + labelo = asm_jmp(OP_EXIT); + + /* Variable assignment and iterated body */ + compile_setq(OP_SETQ, var); + c_tagbody(body); + asm_op(OP_EXIT); + + /* Output */ + asm_complete(OP_EXIT, labelo); + if (CDR(head) != Cnil) + FEerror("Too many arguments to output form of DOLIST", 0); + if (Null(head)) + compile_body(Cnil); + else { + compile_setq(OP_SETQ, var); + compile_form(pop(&head), FALSE); + } + asm_op(OP_EXIT); + + /* Exit point for block */ + asm_complete(op, labelz); + + lex_env = lex_old; +} + + +static void +c_dolist(cl_object args) { + c_dolist_dotimes(OP_DOLIST, args); +} + +static void +c_dotimes(cl_object args) { + c_dolist_dotimes(OP_DOTIMES, args); +} + +static void +c_eval_when(cl_object args) { + cl_object situation = pop(&args); + + if (member_eq(Seval, situation) || member_eq(Kexecute, situation)) + compile_body(args); + else + compile_body(Cnil); +} + + +/* + The OP_FLET/OP_FLABELS operators change the lexical environment + to add a few local functions. + + [OP_FLET/OP_FLABELS + nfun] + fun1 + ... + funn + ... + OP_EXIT + labelz: +*/ +static void +c_labels_flet(int op, cl_object args) { + cl_object def_list = pop(&args); + int nfun = length(def_list); + cl_object lex_old = lex_env; + lex_copy(); + + if (nfun == 0) { + compile_body(args); + return; + } + asm_op2(op, nfun); + do { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + asm1(make_lambda(name, definition)); + } while (!endp(def_list)); + compile_body(args); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + + +static void +c_flet(cl_object args) { + c_labels_flet(OP_FLET, args); +} + + +/* + There are two operators that produce functions. The first one + is + OP_FUNCTION + symbol + which takes the function binding of SYMBOL. The second one is + OP_CLOSE + interpreted + which encloses the INTERPRETED function in the current lexical + environment. +*/ +static void +c_function(cl_object args) { + cl_object function = pop(&args); + if (!endp(args)) + FEerror("Too many arguments to FUNCTION", 0); + if (SYMBOLP(function)) { + asm_op(OP_FUNCTION); + asm1(function); + } else if (CONSP(function) && CAR(function) == Slambda) { + asm_op(OP_CLOSE); + asm1(make_lambda(Cnil, CDR(function))); + } else if (CONSP(function) && CAR(function) == siSlambda_block) { + cl_object name = CADR(function); + cl_object body = CDDR(function); + asm_op(OP_CLOSE); + asm1(make_lambda(name, body)); + } else + FEerror("No a valid argument to FUNCTION ~S", 1, function); +} + + +static void +c_go(cl_object args) { + cl_object tag = pop(&args); + if (!Null(args)) + FEerror("Too many arguments to GO",0); + if (!reference_tag(tag)) + asm_op(OP_JMP); /* Local tag */ + else { + asm_op(OP_GO); /* Tagbody out of closure */ + asm1(tag); + } +} + + +/* + To get an idea of what goes on + + ... ; test form + JNIL labeln + ... ; form for true case + JMP labelz + ... ; form fro nil case + labelz: +*/ +static void +c_if(cl_object form) { + cl_fixnum label_nil, label_true; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_nil = asm_jmp(OP_JNIL); + + /* Compile THEN clause */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JMP); + + /* Compile ELSE clause */ + asm_complete(OP_JNIL, label_nil); + if (!endp(form)) + compile_form(pop(&form), FALSE); + asm_complete(OP_JMP, label_true); + + if (!Null(form)) + FEerror("Too many arguments to IF form", 0); +} + + +static void +c_labels(cl_object args) { + c_labels_flet(OP_LABELS, args); +} + + +/* + The OP_PUSHENV saves the current lexical environment to allow + several bindings. + OP_PUSHENV + ... ; binding forms + ... ; body + OP_EXIT + + There are four forms which perform bindings + OP_PBIND ; Bind NAME in the lexical env. using + name ; a value from the stack + OP_PBINDS ; Bind NAME as special variable using + name ; a value from the stack + OP_BIND ; Bind NAME in the lexical env. using + name ; VALUES(0) + OP_BINDS ; Bind NAME as special variable using + name ; VALUES(0) + + After a variable has been bound, there are several ways to + refer to it. + + 1) Refer to the n-th variable in the lexical environment + [SYMVAL + n] + + 2) Refer to the value of a special variable or constant + SYMVALS + name + + 3) Push the value of the n-th variable of the lexical environment + [PUSHV + n] + + 4) Push the value of a special variable or constant + PUSHVS + name +*/ + +static void +c_let_leta(int op, cl_object args) { + cl_object bindings, specials, body, l, vars; + cl_object lex_old = lex_env; + lex_copy(); + + bindings = car(args); + siLprocess_declarations(1, CDR(args)); + body = VALUES(1); + specials = VALUES(3); + + /* Optimize some common cases */ + switch(length(bindings)) { + case 0: compile_body(body); return; + case 1: op = OP_BIND; break; + default: + } + + asm_op(OP_PUSHENV); + for (vars=Cnil, l=bindings; !endp(l); ) { + cl_object aux = pop(&l); + cl_object var, value; + if (ATOM(aux)) { + var = aux; + value = Cnil; + } else { + var = pop(&aux); + value = pop_maybe_nil(&aux); + if (!Null(aux)) + FEerror("Not a valid argument to LET ~S.", 1, + args); + } + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (op == OP_PBIND) { + compile_form(value, TRUE); + vars = CONS(var, vars); + } else { + compile_form(value, FALSE); + c_bind(var, specials); + } + } + while (!endp(vars)) + c_pbind(pop(&vars), specials); + compile_body(body); + asm_op(OP_EXIT); + + lex_env = lex_old; +} + +static void +c_let(cl_object args) { + c_let_leta(OP_PBIND, args); +} + +static void +c_leta(cl_object args) { + c_let_leta(OP_BIND, args); +} + +/* + MACROLET + + The current lexical environment is saved. A new one is prepared with + the definitions of these macros, and this environment is used to + compile the body. + */ +static void +c_macrolet(cl_object args) +{ + cl_object def_list, def, name; + int nfun = 0; + cl_object lex_old = lex_env; + lex_copy(); + + /* Pop the list of definitions */ + for (def_list = pop(&args); !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object arglist = pop(&definition); + cl_object macro, function; + macro = funcall(4, siSexpand_defmacro, name, arglist, + definition); + function = make_lambda(name, CDR(macro)); + lex_macro_bind(name, function); + } + compile_body(args); + lex_env = lex_old; +} + + +static void +c_multiple_value_bind(cl_object args) +{ + cl_object vars, value, body, specials; + cl_index save_pc, n; + cl_object lex_old = lex_env; + lex_copy(); + + vars = pop(&args); + value = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + compile_form(value, FALSE); + n = length(vars); + if (n == 0) { + compile_body(body); + } else { + asm_op(OP_PUSHENV); + asm_op2(OP_MBIND, n); + for (vars=reverse(vars); n; n--){ + cl_object var = pop(&vars); + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S.", 1, var); + if (special_variablep(var, specials)) { + asm1(MAKE_FIXNUM(1)); + c_register_var(var, TRUE); + } else + c_register_var(var, FALSE); + asm1(var); + } + compile_body(body); + asm_op(OP_EXIT); + } + lex_env = lex_old; +} + + +static void +c_multiple_value_call(cl_object args) { + cl_object name; + + name = pop(&args); + if (endp(args)) { + /* If no arguments, just use ordinary call */ + c_call(list(1, name), FALSE); + return; + } + asm_op(OP_MCALL); + do { + compile_form(pop(&args), FALSE); + asm_op(OP_PUSHVALUES); + } while (!endp(args)); + compile_form(name, FALSE); + asm_op(OP_EXIT); +} + + +static void +c_multiple_value_prog1(cl_object args) { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + asm_op(OP_MPROG1); + compile_body(args); + asm_op(OP_EXIT); + } +} + + +static void +c_multiple_value_setq(cl_object args) { + cl_object orig_vars; + cl_object vars = Cnil; + cl_object temp_vars = Cnil; + cl_object late_assignment = Cnil; + cl_index nvars = 0; + + /* Look for symbol macros, building the list of variables + and the list of late assignments. */ + for (orig_vars = reverse(pop(&args)); !endp(orig_vars); ) { + cl_object aux, v = pop(&orig_vars); + if (!SYMBOLP(v)) + FEerror("Cannot bind ~S", 1, v); + v = macro_expand1(v, CDR(lex_env)); + if (!SYMBOLP(v)) { + aux = v; + v = Lgensym(0); + temp_vars = CONS(v, temp_vars); + late_assignment = CONS(list(3, Ssetf, aux, v), + late_assignment); + } + vars = CONS(v, vars); + nvars++; + } + + if (!Null(temp_vars)) { + asm_op(OP_PUSHENV); + do { + compile_form(Cnil, FALSE); + c_bind(CAR(temp_vars), Cnil); + temp_vars = CDR(temp_vars); + } while (!Null(temp_vars)); + } + + /* Compile values */ + compile_form(pop(&args), FALSE); + if (args != Cnil) + FEerror("Too many arguments to MULTIPLE-VALUE-SETQ",0); + if (nvars == 0) + /* No variables */ + return; + + /* Compile variables */ + asm_op2(OP_MSETQ, nvars); + vars = reverse(vars); + while (nvars--) { + cl_object ndx, var = pop(&vars); + if (!SYMBOLP(var)) + FEerror("MULTIPLE-VALUE-SETQ: ~A is not a symbol", 1, var); + ndx = lex_var_sch(var); + if (!Null(ndx) && CDR(ndx) != Sspecial) + asm1(var); /* Lexical variable */ + else if (var->symbol.stype == stp_constant) + FEerror("MULTIPLE-VALUE-SETQ: Cannot change the value of the constant ~A", 1,var); + else { + asm1(MAKE_FIXNUM(1)); + asm1(var); + } + } + + /* Assign to symbol-macros */ + if (!Null(late_assignment)) { + compile_body(late_assignment); + asm_op(OP_EXIT); + } +} + + +/* + The OP_NTHVAL operator moves a value from VALUES(ndx) to + VALUES(0). The index NDX is taken from the stack. + + OP_NTHVAL +*/ +static void +c_nth_value(cl_object args) { + compile_form(pop(&args), TRUE); /* INDEX */ + compile_form(pop(&args), FALSE); /* VALUES */ + if (args != Cnil) + FEerror("Too many arguments to NTH-VALUE",0); + asm_op(OP_NTHVAL); +} + + +static void +c_or(cl_object args) { + if (Null(args)) { + asm1(Cnil); + return; + } else if (ATOM(args)) { + FEerror("Wrong type of argument to AND ~S", 1, args); + } else { + compile_form(pop(&args), FALSE); + if (!endp(args)) { + cl_index label = asm_jmp(OP_JT); + c_or(args); + asm_complete(OP_JT, label); + } + } +} + + +/* + The OP_PROGV operator exectures a set of statements in a lexical + environment that has been extended with special variables. The + list of special variables is taken from the top of the stack, + while the list of values is in VALUES(0). + + ... ; list of variables + OP_PUSH + ... ; list of values + OP_PROGV + ... ; body of progv + OP_EXIT +*/ +static void +c_progv(cl_object args) { + cl_object vars = pop(&args); + cl_object values = pop(&args); + + /* The list of variables is in the stack */ + compile_form(vars, TRUE); + + /* The list of values is in VALUES(0) */ + compile_form(values, FALSE); + + /* The body is interpreted within an extended lexical + environment. However, as all the new variables are + special, the compiler need not take care of them + */ + asm_op(OP_PROGV); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + There are four assignment operators. They are + + 1) Assign VALUES(0) to the lexical variable which occupies the + N-th position + [OP_SETQ + n] + + 2) Assign VALUES(0) to the special variable NAME + OP_SETQS + name + + 3) Pop a value from the stack and assign it to the lexical + variable in the N-th position. + [OP_PSETQ + n] + + 4) Pop a value from the stack and assign it to the special + variable denoted by NAME + OP_PSETQS + name +*/ +static void +c_psetq(cl_object old_args) { + cl_object args = Cnil, vars = Cnil; + bool use_psetf = FALSE; + cl_index nvars = 0; + + /* We have to make sure that non of the variables which + are to be assigned is actually a symbol macro. If that + is the case, we invoke (PSETF ...) to handle the + macro expansions. + */ + while (!endp(old_args)) { + cl_object var = pop(&old_args); + cl_object value = pop(&old_args); + if (!SYMBOLP(var)) + FEerror("Cannot assign to ~a", 1, var); + var = macro_expand1(var, CDR(lex_env)); + if (!SYMBOLP(var)) + use_psetf = TRUE; + args = CONS(var, CONS(value, args)); + nvars++; + } + if (use_psetf) { + compile_form(CONS(Spsetf, args), FALSE); + return; + } + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + vars = CONS(var, vars); + compile_form(value, TRUE); + } + while (!endp(vars)) + compile_setq(OP_PSETQ, pop(&vars)); +} + + +/* + The OP_RETFROM operator returns from a block using the objects + in VALUES() as output values. + + ... ; output form + OP_RETFROM + tag ; object which names the block +*/ +static void +c_return(cl_object stmt) { + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + asm1(Cnil); + if (stmt != Cnil) + FEerror("Too many arguments to RETURN", 0); +} + + +static void +c_return_from(cl_object stmt) { + cl_object name = pop(&stmt); + cl_object output = pop_maybe_nil(&stmt); + + compile_form(output, FALSE); + asm_op(OP_RETURN); + if (!SYMBOLP(name)) + FEerror("Not a valid return tag ~S", 1, name); + asm1(name); + if (stmt != Cnil) + FEerror("Too many arguments to RETURN-FROM", 0); +} + + +static void +c_setq(cl_object args) { + while (!endp(args)) { + cl_object var = pop(&args); + cl_object value = pop(&args); + if (!SYMBOLP(var)) + FEerror("Cannot bind ~S", 1, var); + var = macro_expand1(var, CDR(lex_env)); + if (SYMBOLP(var)) { + compile_form(value, FALSE); + compile_setq(OP_SETQ, var); + } else { + compile_form(list(3, Ssetf, var, value), FALSE); + } + } +} + + +static void +c_symbol_macrolet(cl_object args) +{ + cl_object def_list, def, name, specials, body; + cl_object lex_old = lex_env; + int nfun = 0; + + /* Set a new lexical environment where we will bind + our macrology */ + lex_copy(); + + def_list = pop(&args); + siLprocess_declarations(1,args); + body = VALUES(1); + specials = VALUES(3); + + /* Scan the list of definitions */ + for (; !endp(def_list); ) { + cl_object definition = pop(&def_list); + cl_object name = pop(&definition); + cl_object expansion = pop(&definition); + cl_object arglist = list(2, Lgensym(0), Lgensym(0)); + cl_object function; + if (special_variablep(name, specials)) + FEerror("Symbol ~A cannot be declared special and appear in a SYMBOL-MACROLET", 1, name); + definition = list(2, arglist, list(2, Squote, expansion)); + function = make_lambda(name, definition); + lex_symbol_macro_bind(name, function); + } + compile_body(body); + lex_env = lex_old; +} + +static void +c_tagbody(cl_object args) +{ + int i, nt; + cl_fixnum label0, labelz; + cl_object body, tag_list; + cl_object lex_old = lex_env; + lex_copy(); + + /* count and register the tags */ + for (nt = 0, tag_list = Cnil, body = args; !endp(body); body = CDR(body)) { + cl_object form = CAR(body); + int type = type_of(form); + if (type == t_symbol || type == t_fixnum || type == t_bignum) { + tag_list = CONS(list(3, form, Stag, Cnil), tag_list); + nt += 1; + } + } + if (nt == 0) { + compile_body(args); + return; + } + label0 = current_pc(); + CDR(lex_env) = nconc(nreverse(tag_list), CDR(lex_env)); + + /* + * We compile the body, storing the address of each label. + */ + for (tag_list = CDR(lex_env), body = args; !endp(body); body = CDR(body)) { + cl_object form = CAR(body); + int type = type_of(form); + if (type == t_symbol || type == t_fixnum || type == t_bignum) { + /* Each label points to a place in the bytecodes + stack. This point is registered at the beginning of + the tag list. */ + cl_object pc = MAKE_FIXNUM(current_pc()); + cl_object tag = CAR(tag_list); + cl_object relocation = CADDR(tag); + CADDR(tag) = CONS(pc, relocation); + tag_list = CDR(tag_list); + } else if (CONSP(form)) { + /* Since the output of all forms is ignored, we + need only compile forms which are not atoms */ + compile_form(form, FALSE); + } + } + /* + * Each (GO ...) form leads to either a local jump, or a jump + * out of a closure. In this loop we fix the destination of those + * local jumps... + */ + for (i = 0, tag_list = Cnil; nt; nt--, CDR(lex_env) = CDDR(lex_env)) { + cl_object tag = CADR(lex_env); + cl_object tag_name = CAR(tag); + cl_object relocation = CADDR(tag); + cl_fixnum pc = fix(pop(&relocation)); + while (!endp(relocation)) { + cl_object jump = pop(&relocation); + if (FIXNUMP(jump)) { + cl_fixnum pc_orig = fix(jump); + asm_at(pc_orig, make_op2(OP_JMP, pc - pc_orig)); + continue; + } + tag_list = nconc(tag_list, + list(2, tag_name, MAKE_FIXNUM(pc))); + i++; + } + } + /* + * ...and in this loop we keep a record of the tags that were + * referenced by nonlocal jumps. This implies inserting an OP_TAGBODY + * operand with its relocation table at LABEL0. + */ + if (!i) + compile_body(Cnil); + else { + cl_fixnum delta = 1 + 2*i; + cl_fixnum label; + asm_op(OP_EXIT); + asm_insert(label0, make_op2(OP_TAGBODY, i)); + while (!endp(tag_list)) { + cl_object name = pop(&tag_list); + cl_fixnum pc = fix(pop(&tag_list)) + delta; + asm_insert(label0, name); label0++; + asm_insert(label0, MAKE_FIXNUM(pc - label0)); label0++; + } + } +} + + +/* + The OP_THROW jumps to an enclosing OP_CATCH whose tag + matches the one of the throw. The tag is taken from the + stack, while the output values are left in VALUES(). +*/ +static void +c_throw(cl_object stmt) { + /* FIXME! Do we apply the right protocol here? */ + cl_object tag = pop(&stmt); + cl_object form = pop(&stmt); + if (stmt != Cnil) + FEerror("Too many argumnents to THROW",0); + compile_form(tag, TRUE); + compile_form(form, FALSE); + asm_op(OP_THROW); +} + + +static void +c_unless(cl_object form) { + cl_fixnum label_true, label_false; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label_true = asm_jmp(OP_JT); + + /* Compile body */ + compile_body(form); + label_false = asm_jmp(OP_JMP); + asm_complete(OP_JT, label_true); + + /* When test failed, output NIL */ + asm1(Cnil); + asm_complete(OP_JMP, label_false); +} + + +static void +c_unwind_protect(cl_object args) { + cl_index label = asm_jmp(OP_UNWIND); + + /* Compile form to be protected */ + compile_form(pop(&args), FALSE); + asm_op(OP_EXIT); + + /* Compile exit clause */ + asm_complete(OP_UNWIND, label); + compile_body(args); + asm_op(OP_EXIT); +} + + +/* + The OP_VALUES moves N values from the stack to VALUES(). + + [OP_VALUES + n] +*/ +static void +c_values(cl_object args) { + int n = 0; + + while (!endp(args)) { + compile_form(pop_maybe_nil(&args), TRUE); + n++; + } + asm_op2(OP_VALUES, n); +} + + +static void +c_when(cl_object form) { + cl_fixnum label; + + /* Compile test */ + compile_form(pop(&form), FALSE); + label = asm_jmp(OP_JNIL); + + /* Compile body */ + compile_body(form); + asm_complete(OP_JNIL, label); +} + + +static void +compile_form(cl_object stmt, bool push) { + compiler_record *l; + cl_object function; + cl_object macro; + + /* FIXME! We should protect this region with error handling */ + BEGIN: + /* + * First try with variable references and quoted constants + */ + if (ATOM(stmt)) { + if (SYMBOLP(stmt)) { + if (push) asm_op(OP_PUSHV); + asm1(stmt); + goto OUTPUT; + } + QUOTED: + if (push) + asm_op(OP_PUSHQ); + else if (FIXNUMP(stmt) || SYMBOLP(stmt)) + asm_op(OP_QUOTE); + asm1(stmt); + goto OUTPUT; + } + LIST: + /* + * Next try with special forms. + */ + function = CAR(stmt); + if (!SYMBOLP(function)) + goto ORDINARY_CALL; + if (function == Squote) { + stmt = CDR(stmt); + if (CDR(stmt) != Cnil) + FEerror("Too many arguments to QUOTE",0); + stmt = CAR(stmt); + goto QUOTED; + } + for (l = database; l->symbol != OBJNULL; l++) + if (l->symbol == function) { + (*(l->compiler))(CDR(stmt)); + if (push) asm_op(OP_PUSH); + goto OUTPUT; + } + /* + * Next try to macroexpand + */ + { + cl_object new_stmt = macro_expand1(stmt, CDR(lex_env)); + if (new_stmt != stmt){ + stmt = new_stmt; + goto BEGIN; + } + } + if (function->symbol.isform) + FEerror("Found no macroexpander for special form ~S", 1, function); + ORDINARY_CALL: + /* + * Finally resort to ordinary function calls. + */ + c_call(stmt, push); + OUTPUT: +} + + +static void +compile_body(cl_object body) { + if (endp(body)) + asm_op(OP_NOP); + else do { + compile_form(CAR(body), FALSE); + body = CDR(body); + } while (!endp(body)); +} + +/* ----------------------------- PUBLIC INTERFACE ---------------------------- */ + +/* ------------------------------------------------------------ + LAMBDA OBJECTS: An interpreted function is a vector made of + the following components + + #(LAMBDA + {block-name | NIL} + {variable-env | NIL} + {function-env | NIL} + {block-env | NIL} + (list of variables declared special) + Nreq {var}* ; required arguments + Nopt {var value flag}* ; optional arguments + {rest-var NIL} ; rest variable + {T | NIL} ; allow other keys? + Nkey {key var value flag}* ; keyword arguments + Naux {var init} ; auxiliary variables + documentation-string + list-of-declarations + {form}* ; body) + + ------------------------------------------------------------ */ + +#define push(v,l) l = CONS(v, l) +#define push_var(v, list) \ + check_symbol(v); \ + if (v->symbol.stype == stp_constant) \ + FEerror("~S is not a variable.", 1, v); \ + push(v, list); + +/* + Handles special declarations, removes declarations from body + */ +@(defun si::process_declarations (body &optional doc) + cl_object documentation = Cnil, declarations = Cnil, form, specials = Cnil; + cl_object decls, vars, v; +@ + /* BEGIN: SEARCH DECLARE */ + for (; !endp(body); body = CDR(body)) { + form = CAR(body); + + if (!Null(doc) && type_of(form) == t_string) { + if (documentation == Cnil) + documentation = form; + else + break; + continue; + } + + if (ATOM(form) || (CAR(form) != Sdeclare)) + break; + + for (decls = CDR(form); !endp(decls); decls = CDR(decls)) { + cl_object sentence = CAR(decls); + if (ATOM(sentence)) + FEerror("Illegal declaration form", 1, form); + push(sentence, declarations); + if (CAR(sentence) == Sspecial) + for (vars = CDR(sentence); !endp(vars); vars = CDR(vars)) { + v = CAR(vars); + check_symbol(v); + push(v,specials); + } + } + } + /* END: SEARCH DECLARE */ + + @(return declarations body documentation specials) +@) + +@(defun si::process_lambda_list (lambda) + cl_object documentation, declarations, specials; + cl_object lambda_list, body, form; + cl_object x, v, key, init, spp; + cl_object reqs = Cnil, opts = Cnil, keys = Cnil, rest = Cnil, auxs = Cnil; + int nreq = 0, nopt = 0, nkey = 0, naux = 0; + cl_object allow_other_keys = Cnil; +@ + bds_check; + if (ATOM(lambda)) + FEerror("No lambda list.", 0); + lambda_list = CAR(lambda); + + declarations = siLprocess_declarations(2, CDR(lambda), Ct); + body = VALUES(1); + documentation = VALUES(2); + specials = VALUES(3); + +REQUIRED: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAoptional) + goto OPTIONAL; + if (v == SArest) + goto REST; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + nreq++; + push_var(v, reqs); + } +OPTIONAL: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + spp = Cnil; + init = Cnil; + if (ATOM(x)) { + if (x == SAoptional || x == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (x == SArest) + goto REST; + if (x == SAkey) + goto KEYWORD; + if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + nopt++; + push_var(v, opts); + push(init, opts); + if (spp != Cnil) { + push_var(spp, opts); + } else { + push(Cnil, opts); + } + } + +REST: + if (endp(lambda_list)) + goto ILLEGAL_LAMBDA; + v = CAR(lambda_list); + push_var(v, rest); + + lambda_list = CDR(lambda_list); + if (endp(lambda_list)) + goto OUTPUT; + v = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (v == SAoptional || v == SArest || v == SAallow_other_keys) + goto ILLEGAL_LAMBDA; + if (v == SAkey) + goto KEYWORD; + if (v == SAaux) + goto AUX; + goto ILLEGAL_LAMBDA; + +KEYWORD: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + init = Cnil; + spp = Cnil; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAallow_other_keys) { + if (!Null(allow_other_keys)) + goto ILLEGAL_LAMBDA; + allow_other_keys = Ct; + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (key != SAaux) + goto ILLEGAL_LAMBDA; + goto AUX; + } else if (x == SAoptional || x == SArest || x == SAkey) + goto ILLEGAL_LAMBDA; + else if (x == SAaux) + goto AUX; + v = x; + } else { + v = CAR(x); + if (!endp(x = CDR(x))) { + init = CAR(x); + if (!endp(x = CDR(x))) { + spp = CAR(x); + if (!endp(CDR(x))) + goto ILLEGAL_LAMBDA; + } + } + } + if (CONSP(v)) { + x = v; + key = CAR(x); + if (key->symbol.hpack != keyword_package) + FEerror("~S is not a keyword", 1, key); + if (endp(CDR(x)) || !endp(CDDR(x))) + goto ILLEGAL_LAMBDA; + v = CADR(x); + } else { + check_symbol(v); + key = intern(v->symbol.name, keyword_package); + } + nkey++; + push(key, keys); + push_var(v, keys); + push(init, keys); + if (Null(spp)) { + push(Cnil, keys); + } else { + push_var(spp, keys); + } + } + +AUX: + while (1) { + if (endp(lambda_list)) + goto OUTPUT; + x = CAR(lambda_list); + lambda_list = CDR(lambda_list); + if (ATOM(x)) { + if (x == SAoptional || x == SArest || + x == SAkey || x == SAallow_other_keys || + x == SAaux) + goto ILLEGAL_LAMBDA; + v = x; + init = Cnil; + } else if (endp(CDDR(x))) { + v = CAR(x); + init = CADR(x); + } else + goto ILLEGAL_LAMBDA; + naux++; + push_var(v, auxs); + push(init, auxs); + } + +OUTPUT: + @(return CONS(MAKE_FIXNUM(nreq), nreverse(reqs)) + CONS(MAKE_FIXNUM(nopt), nreverse(opts)) + nreverse(rest) + allow_other_keys + CONS(MAKE_FIXNUM(nkey), nreverse(keys)) + nreverse(auxs) + documentation + specials + declarations + body) + +ILLEGAL_LAMBDA: + FEerror("Illegal lambda list ~S.", 1, CAR(lambda)); +@) + +static void +c_default(cl_index deflt_pc) { + cl_object deflt = asm_ref(deflt_pc); + enum cl_type t = type_of(deflt); + if ((t == t_symbol) && (deflt->symbol.stype == stp_constant)) + /* FIXME! Shouldn't this happen only in unsafe mode */ + asm_at(deflt_pc, SYM_VAL(deflt)); + else if ((t == t_symbol) || (t == t_cons) || (t == t_fixnum)) { + cl_index pc = current_pc(); + asm_at(deflt_pc, MAKE_FIXNUM(pc-deflt_pc)); + compile_form(deflt, FALSE); + asm_op(OP_EXIT); + } +} + +static void +c_register_var2(register cl_object var, register cl_object *specials) +{ + if (Null(var)) + return; + if (member_eq(var, *specials)) + c_register_var(var, TRUE); + else if (var->symbol.stype == stp_special) { + *specials = CONS(var, *specials); + c_register_var(var, TRUE); + } else if (var->symbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + c_register_var(var, FALSE); +} + +cl_object +make_lambda(cl_object name, cl_object lambda) { + cl_object reqs, opts, rest, keys, auxs, allow_other_keys; + cl_object specials, doc, decl, body, l; + cl_index specials_pc, opts_pc, keys_pc, label; + int nopts, nkeys; + cl_index handle; + cl_object lex_old = lex_env; + + lex_copy(); + + /* Mark closure boundary */ + CDR(lex_env) = CONS(CONS(Ct, Cnil), CDR(lex_env)); + + reqs = siLprocess_lambda_list(1,lambda); + opts = VALUES(1); + rest = VALUES(2); + allow_other_keys = VALUES(3); + keys = VALUES(4); + auxs = VALUES(5); + doc = VALUES(6); + specials = VALUES(7); + decl = VALUES(8); + body = VALUES(9); + + handle = asm_begin(); + + asm1(name); /* Name of the function */ + specials_pc = current_pc(); /* Which variables are declared special */ + asm1(specials); + + asm_list(reqs); /* Special arguments */ + reqs = CDR(reqs); + while (!endp(reqs)) { + cl_object v = pop(&reqs); + c_register_var2(v, &specials); + } + + opts_pc = current_pc()+1; /* Optional arguments */ + nopts = fix(CAR(opts)); + asm_list(opts); + + asm_list(rest); /* Name of &rest argument */ + + asm1(allow_other_keys); /* Value of &allow-other-keys */ + + keys_pc = current_pc()+1; /* Keyword arguments */ + nkeys = fix(CAR(keys)); + asm_list(keys); + asmn(2, doc, decl); + + label = asm_jmp(OP_JMP); + + while (nopts--) { + c_default(opts_pc+1); + c_register_var2(asm_ref(opts_pc), &specials); + c_register_var2(asm_ref(opts_pc+2), &specials); + opts_pc+=3; + } + c_register_var2(car(rest), &specials); + while (nkeys--) { + c_default(keys_pc+2); + c_register_var2(asm_ref(keys_pc+1), &specials); + c_register_var2(asm_ref(keys_pc+3), &specials); + keys_pc+=4; + } + + if ((current_pc() - label) == 1) + set_pc(label); + else + asm_complete(OP_JMP, label); + while (!endp(auxs)) { /* Local bindings */ + cl_object var = pop(&auxs); + cl_object value = pop(&auxs); + compile_form(value, FALSE); + c_bind(var, specials); + } + asm_at(specials_pc, specials); + compile_body(body); + asm_op(OP_HALT); + + lex_env = lex_old; + + return asm_end(handle); +} + +static cl_object +alloc_bytecodes() +{ + cl_object vector = alloc_simple_vector(128, aet_object); + array_allocself(vector); + vector->vector.hasfillp = TRUE; + vector->vector.fillp = 0; + return vector; +} + +@(defun si::make_lambda (name rest) + cl_object lambda, old_bytecodes = bytecodes; + cl_object lex_old = lex_env; +@ + lex_new(); + bytecodes = alloc_bytecodes(); + lambda = make_lambda(name,rest); + bytecodes = old_bytecodes; + lex_env = lex_old; + @(return lambda) +@) + +cl_object +eval(cl_object form, cl_object *new_bytecodes) +{ + cl_object old_bytecodes = bytecodes; + cl_index handle; + + if (new_bytecodes == NULL) + bytecodes = alloc_bytecodes(); + else if (*new_bytecodes != Cnil) { + bytecodes = *new_bytecodes; + } else { + bytecodes = *new_bytecodes = alloc_bytecodes(); + } + handle = asm_begin(); + compile_form(form, FALSE); + asm_op(OP_EXIT); + asm_op(OP_HALT); +/* Lprint(1,bytecodes); */ + VALUES(0) = Cnil; + NValues = 0; + interpret(&bytecodes->vector.self.t[handle]); + asm_clear(handle); + bytecodes = old_bytecodes; + return VALUES(0); +} + +void +init_compiler(void) +{ + compiler_record *l; + + register_root(&bytecodes); + + for (l = database; l->name[0] != 0; l++) + l->symbol = _intern(l->name, lisp_package); +} diff --git a/src/c/old/interpreter.d b/src/c/old/interpreter.d new file mode 100644 index 000000000..150ae7e50 --- /dev/null +++ b/src/c/old/interpreter.d @@ -0,0 +1,874 @@ +/* + interpreter.c -- Bytecode interpreter. +*/ +/* + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include "ecls-inl.h" +#include "bytecodes.h" + +#define next_code(v) *(v++) + +static void +lambda_bind_var(cl_object var, cl_object val, cl_object specials) +{ + if (!member_eq(var, specials)) + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); + else { + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); + } +} + +static void +bind_var(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, CONS(val, Cnil)), CAR(lex_env)); +} + +static void +bind_special(register cl_object var, register cl_object val) +{ + CAR(lex_env) = CONS(CONS(var, Cnil), CAR(lex_env)); + bds_bind(var, val); +} + +static cl_object * +lambda_bind(int narg, cl_object lambda_list, cl_object *args) +{ + cl_object *data = &lambda_list->bytecodes.data[2]; + cl_object specials = lambda_list->bytecodes.data[1]; + cl_object aux; + int i, n; + bool other_keys = FALSE; + bool check_remaining = TRUE; + + /* 1) REQUIRED ARGUMENTS: N var1 ... varN */ + n = fix(next_code(data)); + if (narg < n) + check_arg_failed(narg, n); + for (; n; n--, narg--) + lambda_bind_var(next_code(data), next_code(args), specials); + + /* 2) OPTIONAL ARGUMENTS: N var1 value1 flag1 ... varN valueN flagN */ + for (n = fix(next_code(data)); n; n--, data+=3) { + if (narg) { + lambda_bind_var(data[0], args[0], specials); + args++; narg--; + if (!Null(data[2])) + lambda_bind_var(data[2], Ct, specials); + } else { + cl_object defaults = data[1]; + if (FIXNUMP(defaults)) { + interpret(&data[1] + fix(defaults)); + defaults = VALUES(0); + } + lambda_bind_var(data[0], defaults, specials); + if (!Null(data[2])) + lambda_bind_var(data[2], Cnil, specials); + } + } + + /* 3) REST ARGUMENT: {rest-var | NIL} */ + if (!Null(data[0])) { + cl_object rest = Cnil; + check_remaining = FALSE; + for (i=narg; i; ) + rest = CONS(args[--i], rest); + lambda_bind_var(data[0], rest, specials); + } + data++; + + /* 4) ALLOW-OTHER-KEYS: { T | NIL } */ + other_keys = !Null(next_code(data)); + + /* 5) KEYWORDS: N key1 var1 value1 flag1 ... keyN varN valueN flagN */ + n = fix(next_code(data)); + if (n != 0 || other_keys) { + cl_object *keys; + cl_object spp[n]; + bool other_found = FALSE; + for (i=0; isymbol.hpack != keyword_package) + FEerror("Not a keyword ~S.", 1, args[0]); + keys = data; + for (i = 0; i < n; i++, keys += 4) { + if (args[0] == keys[0]) { + if (spp[i] == OBJNULL) + spp[i] = args[1]; + goto FOUND; + } + } + if (args[0] != SAallow_other_keys) + other_found = TRUE; + else + other_keys = (args[1] == Cnil); + FOUND: + } + if (other_found && !other_keys) + FEerror("Unknown keys found", 0); + for (i=0; ibytecodes.data[0]); + + return &data[2]; +} + +cl_object +lambda_apply(int narg, cl_object fun, cl_object *args) +{ cl_object lex_old = lex_env; + cl_object output, name, *body; + bds_ptr old_bds_top; + volatile bool block, closure; + + if (type_of(fun) != t_bytecodes) + FEinvalid_function(fun); + + /* Set the lexical environment of the function */ + ihs_check; + if (Null(fun->bytecodes.lex)) + lex_env = CONS(Cnil, Cnil); + else + lex_env = CONS(CAR(fun->bytecodes.lex),CDR(fun->bytecodes.lex)); + ihs_push(fun, lex_env); + old_bds_top = bds_top; + + /* Establish bindings */ + body = lambda_bind(narg, fun, args); + + /* If it is a named lambda, set a block for RETURN-FROM */ + block = FALSE; + name = fun->bytecodes.data[0]; + if (Null(fun->bytecodes.data[0])) + block = FALSE; + else { + block = TRUE; + fun = new_frame_id(); + lex_block_bind(name, fun); + if (frs_push(FRS_CATCH, fun)) { + output = VALUES(0); + goto END; + } + } + + /* Process statements */ + VALUES(0) = Cnil; + NValues = 0; + interpret(body); + +END: if (block) frs_pop(); + bds_unwind(old_bds_top); + lex_env = lex_old; + ihs_pop(); + returnn(VALUES(0)); +} + + +/* ----------------- BYTECODE STACK --------------- */ + +cl_object stack = OBJNULL; + +static void +stack_grow(void) { + cl_object *old_data = stack->vector.self.t; + cl_index old_size = stack->vector.fillp; + stack->vector.dim += 128; + array_allocself(stack); + memcpy(stack->vector.self.t, old_data, old_size*sizeof(cl_object)); +} + +static void +push1(register cl_object op) { + cl_index where; + where = stack->vector.fillp; + if (where >= stack->vector.dim) + stack_grow(); + stack->vector.self.t[where] = op; + stack->vector.fillp++; +} + +static cl_object +pop1() { + return stack->vector.self.t[--stack->vector.fillp]; +} + +static cl_index +get_sp_index() { + return stack->vector.fillp; +} + +static void +dec_sp_index(register cl_index delta) { + stack->vector.fillp -= delta; +} + +static void +set_sp_index(register cl_index sp) { + if (stack->vector.fillp < sp) + FEerror("Tried to advance stack", 0); + stack->vector.fillp = sp; +} + +static cl_object * +get_sp() { + return stack->vector.self.t + stack->vector.fillp; +} + +static cl_object * +get_sp_at(cl_index where) { + return stack->vector.self.t + where; +} + +/* -------------------- AIDS TO THE INTERPRETER -------------------- */ + +static inline cl_fixnum +get_oparg(cl_object o) { + return GET_OPARG(o); +} + +static inline cl_object * +packed_label(cl_object *v) { + return v + GET_OPARG(v[0]); +} + +static inline cl_object * +simple_label(cl_object *v) { + return v + fix(v[0]); +} + +static cl_object +search_symbol_function(register cl_object fun) { + cl_object output = lex_fun_sch(fun); + if (!Null(output)) + return output; + output = SYM_FUN(fun); + if (output == OBJNULL || fun->symbol.mflag) + FEundefined_function(fun); + return output; +} + +static cl_object +search_symbol_value(register cl_object s) { + cl_object x; + /* x = lex_var_sch(form); */ + for (x = CAR(lex_env); CONSP(x); x = CDR(x)) + if (CAAR(x) == s) { + x = CDAR(x); + if (ENDP(x)) break; + return CAR(x); + } + x = SYM_VAL(s); + if (x == OBJNULL) + FEunbound_variable(s); + return x; +} + +static cl_object +interpret_apply(int narg, cl_object fun, cl_object *args) { + cl_object x; + + AGAIN: + switch (type_of(fun)) { + case t_cfun: + ihs_push_funcall(fun->cfun.name); + x = APPLY(narg, fun->cfun.entry, args); + ihs_pop(); + return x; + case t_cclosure: + /* FIXME! Shouldn't we register this call somehow? */ + return APPLY_closure(narg, fun->cclosure.entry, fun->cclosure.env, args); +#ifdef CLOS + case t_gfun: + ihs_push_funcall(fun->gfun.name); + x = gcall(narg, fun, args); + ihs_pop(); + return x; +#endif + case t_bytecodes: + return lambda_apply(narg, fun, args); + case t_symbol: + fun = search_symbol_function(fun); + goto AGAIN; + default: + } + FEinvalid_function(fun); +} + +/* -------------------- THE INTERPRETER -------------------- */ + +static cl_object * +interpret_block(cl_object *vector) { + cl_object * volatile exit, name; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + lex_copy(); + + exit = packed_label(vector - 1); + lex_block_bind(next_code(vector), id); + if (frs_push(FRS_CATCH,id) == 0) + vector = interpret(vector); + frs_pop(); + lex_env = lex_old; + return exit; +} + +static cl_object * +interpret_catch(cl_object *vector) { + cl_object * volatile exit; + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,VALUES(0)) == 0) + interpret(vector); + frs_pop(); + return exit; +} + +static cl_object * +interpret_tagbody(cl_object *vector) { + cl_index i, ntags = fix(get_oparg(vector[-1])); + cl_object lex_old = lex_env; + cl_object id = new_frame_id(); + cl_object *aux, *tag_list = vector; + + lex_copy(); + aux = vector; + for (i=0; i= ntags) + FEerror("Someone tried to RETURN-FROM a TAGBODY",0); + else + aux = simple_label(aux); + } + vector = interpret(aux); + frs_pop(); + lex_env = lex_old; + VALUES(0) = Cnil; + NValues = 0; + return vector; +} + +static cl_object * +interpret_unwind_protect(cl_object *vector) { + bool unwinding; + int nr; + cl_object * volatile exit; + + exit = packed_label(vector-1); + if (frs_push(FRS_PROTECT, Cnil)) + unwinding = TRUE; + else { + interpret(vector); + unwinding = FALSE; + } + nr = NValues; + MV_SAVE(nr); + exit = interpret(exit); + MV_RESTORE(nr); + frs_pop(); + if (unwinding) + unwind(nlj_fr, nlj_tag); + return exit; +} + +static cl_object * +interpret_do(cl_object *vector) { + cl_object *volatile exit; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + exit = packed_label(vector-1); + if (frs_push(FRS_CATCH,id) == 0) + interpret(vector); + frs_pop(); + + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dolist(cl_object *vector) { + cl_object *output, *volatile exit; + cl_object list, var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + list = VALUES(0); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Build list & bind variable*/ + vector = interpret(vector); + output = packed_label(vector-1); + while (!endp(list)) { + NValues = 1; + VALUES(0) = CAR(list); + interpret(vector); + list = CDR(list); + } + VALUES(0) = Cnil; + NValues = 1; + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object * +interpret_dotimes(cl_object *vector) { + cl_object *output, *volatile exit; + cl_fixnum length, i; + cl_object var; + cl_object id = new_frame_id(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + lex_copy(); + lex_block_bind(Cnil, id); + + length = fix(VALUES(0)); + exit = packed_label(vector - 1); + if (frs_push(FRS_CATCH,id) == 0) { + /* Bind variable */ + vector = interpret(vector); + output = packed_label(vector-1); + for (i = 0; i < length;) { + interpret(vector); + NValues = 1; + VALUES(0) = MAKE_FIXNUM(++i); + } + interpret(output); + } + frs_pop(); + lex_env = lex_old; + bds_unwind(old_bds_top); + return exit; +} + +static cl_object +close_around(cl_object fun, cl_object lex) { + cl_object v = alloc_object(t_bytecodes); + v->bytecodes.size = fun->bytecodes.size; + v->bytecodes.data = fun->bytecodes.data; + if (!Null(CAR(lex)) || !Null(CDR(lex))) + v->bytecodes.lex = CONS(CAR(lex),CDR(lex)); + else + v->bytecodes.lex = Cnil; + return v; +} + +static cl_object * +interpret_flet(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index nfun = get_oparg(vector[-1]); + + lex_copy(); + while (nfun--) { + cl_object fun = next_code(vector); + cl_object f = close_around(fun,lex_old); + lex_fun_bind(f->bytecodes.data[0], f); + } + vector = interpret(vector); + lex_env = lex_old; + return vector; +} + +static cl_object * +interpret_labels(cl_object *vector) { + cl_object lex_old = lex_env; + cl_index i, nfun = get_oparg(vector[-1]); + cl_object l; + + lex_copy(); + for (i=0; ibytecodes.data[0], f); + } + /* Update the closures so that all functions can call each other */ + for (i=0, l=CDR(lex_env); isymbol.stype == stp_constant) + FEerror("Cannot set the constant ~A", 1, var); + else + SYM_VAL(var) = value; + } + } + if (NValues > 1) NValues = 1; + return vector; +} + +static cl_object * +interpret_progv(cl_object *vector) { + cl_object values = VALUES(0); + cl_object vars = pop1(); + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + while (!endp(vars)) { + if (values == Cnil) + bds_bind(CAR(vars), OBJNULL); + else { + bds_bind(CAR(vars), car(values)); + values = CDR(values); + } + vars = CDR(vars); + } + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +static cl_object * +interpret_pushenv(cl_object *vector) { + cl_object lex_old = lex_env; + bds_ptr old_bds_top = bds_top; + + lex_copy(); + vector = interpret(vector); + lex_env = lex_old; + bds_unwind(old_bds_top); + return vector; +} + +cl_object * +interpret(cl_object *vector) { + enum cl_type t; + cl_object s; + cl_fixnum n; + + BEGIN: + s = next_code(vector); + t = type_of(s); + if (t == t_symbol) { + VALUES(0) = search_symbol_value(s); + NValues = 1; + goto BEGIN; + } + if (t != t_fixnum) { + VALUES(0) = s; + NValues = 1; + goto BEGIN; + } + switch (GET_OP(s)) { + case OP_PUSHQ: + push1(next_code(vector)); + break; + case OP_PUSH: + push1(VALUES(0)); + break; + case OP_PUSHV: + push1(search_symbol_value(next_code(vector))); + break; + case OP_QUOTE: + VALUES(0) = next_code(vector); + NValues = 1; + break; + case OP_NOP: + VALUES(0) = Cnil; + NValues = 0; + break; + case OP_BLOCK: + vector = interpret_block(vector); + break; + case OP_PUSHVALUES: { + int i; + for (i=0; isymbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + SYM_VAL(var) = VALUES(0); + break; + } + case OP_PBIND: + bind_var(next_code(vector), pop1()); + break; + case OP_PBINDS: + bind_special(next_code(vector), pop1()); + break; + case OP_PSETQ: + CADR(lex_var_sch(next_code(vector))) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + case OP_PSETQS: { + cl_object var = next_code(vector); + if (var->symbol.stype == stp_constant) + FEerror("Cannot bind the constant ~A", 1, var); + else + SYM_VAL(var) = pop1(); + Values[0] = Cnil; + NValues = 1; + break; + } + case OP_MSETQ: + vector = interpret_msetq(vector); + break; + case OP_MBIND: + vector = interpret_mbind(vector); + break; + case OP_MPROG1: + vector = interpret_mprog1(vector); + break; + case OP_PROGV: + vector = interpret_progv(vector); + break; + case OP_PUSHENV: + vector = interpret_pushenv(vector); + break; + case OP_VALUES: { + cl_fixnum n = get_oparg(s); + NValues = n; + while (n) + VALUES(--n) = pop1(); + break; + } + case OP_NTHVAL: { + cl_index n = fix(pop1()); + if (n < 0 || n >= NValues) + VALUES(0) = Cnil; + else + VALUES(0) = VALUES(n); + NValues = 1; + break; + } + case OP_DOLIST: + vector = interpret_dolist(vector); + break; + case OP_DOTIMES: + vector = interpret_dotimes(vector); + break; + case OP_DO: + vector = interpret_do(vector); + break; + case OP_TAGBODY: + vector = interpret_tagbody(vector); + break; + case OP_UNWIND: + vector = interpret_unwind_protect(vector); + break; + default: + FEerror("Unknown code ~S", 1, MAKE_FIXNUM(*(vector-1))); + } + goto BEGIN; +} + +@(defun si::interpreter_stack () +@ + @(return stack) +@) + +void +init_interpreter(void) +{ + register_root(&stack); + stack = alloc_simple_vector(128, aet_object); + array_allocself(stack); + stack->vector.hasfillp = TRUE; + stack->vector.fillp = 0; +} diff --git a/src/c/package.d b/src/c/package.d new file mode 100644 index 000000000..9b5a56d73 --- /dev/null +++ b/src/c/package.d @@ -0,0 +1,930 @@ +/* + package.d -- Packages. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +bool lisp_package_locked = FALSE; +cl_object lisp_package; +cl_object user_package; +cl_object keyword_package; +cl_object system_package; +#ifdef CLOS +cl_object clos_package; +#endif +#ifdef TK +cl_object tk_package; +#endif +cl_object Vpackage; /* *package* */ + +#ifndef THREADS +int intern_flag; +#endif + +cl_object Kinternal; +cl_object Kexternal; +cl_object Kinherited; +cl_object Knicknames; +cl_object Kuse; + +/******************************* ------- ******************************/ + +#define INTERNAL 1 +#define EXTERNAL 2 +#define INHERITED 3 + +static cl_object package_list = Cnil; +static cl_object uninterned_list = Cnil; + +static void no_package(cl_object n) __attribute__((noreturn)); +static void package_already(cl_object n) __attribute__((noreturn)); + +static void +no_package(cl_object n) +{ + FEerror("There is no package with the name ~A.", 1, n); +} + +static void +package_already(cl_object n) +{ + FEerror("A package with the name ~A already exists.", 1, n); +} + +static bool +member_string_eq(cl_object x, cl_object l) +{ + /* INV: l is a proper list */ + for (; CONSP(l); l = CDR(l)) + if (string_eq(x, CAR(l))) + return(TRUE); + return(FALSE); +} + +/* + Make_package(n, ns, ul) makes a package with name n, + which must be a string or a symbol, + and nicknames ns, which must be a list of strings or symbols, + and uses packages in list ul, which must be a list of packages + or package names i.e. strings or symbols. +*/ +static cl_object +make_package_hashtable() +{ + cl_object h; + cl_index hsize = 128, i; + + h = alloc_object(t_hashtable); + h->hash.test = htt_pack; + h->hash.size = hsize; + h->hash.rehash_size = make_shortfloat(1.5); + h->hash.threshold = make_shortfloat(0.7); + h->hash.entries = 0; + h->hash.data = alloc(hsize * sizeof(struct hashtable_entry)); + for(i = 0; i < hsize; i++) { + h->hash.data[i].key = OBJNULL; + h->hash.data[i].value = OBJNULL; + } + return h; +} + +cl_object +make_package(cl_object name, cl_object nicknames, cl_object use_list) +{ + cl_object x, y; + cl_index i; + + name = coerce_to_string(name); + assert_type_proper_list(nicknames); + assert_type_proper_list(use_list); + + if (find_package(name) != Cnil) + package_already(name); + x = alloc_object(t_package); + x->pack.name = name; + x->pack.nicknames = Cnil; + x->pack.shadowings = Cnil; + x->pack.uses = Cnil; + x->pack.usedby = Cnil; + x->pack.locked = FALSE; + for (; !endp(nicknames); nicknames = CDR(nicknames)) { + cl_object nick = coerce_to_string(CAR(nicknames)); + if (find_package(nick) != Cnil) + package_already(nick); + x->pack.nicknames = CONS(nick, x->pack.nicknames); + } + for (; !endp(use_list); use_list = CDR(use_list)) { + if (type_of(CAR(use_list)) == t_package) + y = CAR(use_list); + else { + y = find_package(CAR(use_list)); + if (Null(y)) + no_package(CAR(use_list)); + } + x->pack.uses = CONS(y, x->pack.uses); + y->pack.usedby = CONS(x, y->pack.usedby); + } + x->pack.internal = make_package_hashtable(); + x->pack.external = make_package_hashtable(); + package_list = CONS(x, package_list); + return(x); +} + +cl_object +rename_package(cl_object x, cl_object name, cl_object nicknames) +{ + cl_object y; + + /* + If we are trying to rename the package with either its name + or a nickname, then we are really trying to redefine the + package. Therefore, do not signal the error. + + Marco Antoniotti 19951028 + */ + x = coerce_to_package(x); + name = coerce_to_string(name); + y = find_package(name); + if ((y != Cnil) && (y != x)) + package_already(name); + + x->pack.name = name; + x->pack.nicknames = Cnil; + assert_type_proper_list(nicknames); + for (; !endp(nicknames); nicknames = CDR(nicknames)) { + cl_object nick = CAR(nicknames); + y = find_package(nick); + if (x == y) + continue; + if (y != Cnil) + package_already(nick); + x->pack.nicknames = CONS(coerce_to_string(nick), x->pack.nicknames); + } + return(x); +} + +/* + Find_package(n) seaches for a package with name n, where n is + a valid string designator, or simply outputs n if it is a + package. +*/ +cl_object +find_package(cl_object name) +{ + cl_object l, p; + + if (type_of(name) == t_package) + return name; + name = coerce_to_string_designator(name); + /* INV: package_list is a proper list */ + for (l = package_list; CONSP(l); l = CDR(l)) { + p = CAR(l); + if (string_eq(name, p->pack.name)) + return p; + if (member_string_eq(name, p->pack.nicknames)) + return p; + } + return Cnil; +} + +cl_object +coerce_to_package(cl_object p) +{ + cl_object pp; + if (type_of(p) == t_package) + return(p); + pp = find_package(p); + if (!Null(pp)) + return (pp); + FEwrong_type_argument(Spackage, p); +} + +cl_object +current_package(void) +{ + cl_object x; + + x = symbol_value(Vpackage); + if (type_of(x) != t_package) { + SYM_VAL(Vpackage) = user_package; + FEerror("The value of *PACKAGE*, ~S, was not a package.", + 1, x); + } + return(x); +} + +/* + Intern(st, p) interns string st in package p. +*/ +cl_object +_intern(const char *s, cl_object p) +{ + cl_object str = make_simple_string(s); + return intern(str, p); +} + +cl_object +intern(cl_object name, cl_object p) +{ + cl_object s, ul; + + assert_type_string(name); + p = coerce_to_package(p); + s = gethash_safe(name, p->pack.external, OBJNULL); + if (s != OBJNULL) { + intern_flag = EXTERNAL; + return s; + } + /* Keyword package has no intern section nor can it be used */ + if (p == keyword_package) goto INTERN; + s = gethash_safe(name, p->pack.internal, OBJNULL); + if (s != OBJNULL) { + intern_flag = INTERNAL; + return s; + } + for (ul=p->pack.uses; CONSP(ul); ul = CDR(ul)) { + s = gethash_safe(name, CAR(ul)->pack.external, OBJNULL); + if (s != OBJNULL) { + intern_flag = INHERITED; + return s; + } + } + INTERN: + s = make_symbol(name); + s->symbol.hpack = p; + intern_flag = 0; + if (p == keyword_package) { + s->symbol.stype = stp_constant; + SYM_VAL(s) = s; + sethash(name, p->pack.external, s); + } else { + sethash(name, p->pack.internal, s); + } + return s; +} + +/* + Find_symbol(st, len, p) searches for string st of length len in package p. +*/ +cl_object +find_symbol(cl_object name, cl_object p) +{ + cl_object s, ul; + + name = coerce_to_string_designator(name); + p = coerce_to_package(p); + s = gethash_safe(name, p->pack.external, OBJNULL); + if (s != OBJNULL) { + intern_flag = EXTERNAL; + return s; + } + if (p == keyword_package) goto RETURN; + s = gethash_safe(name, p->pack.internal, OBJNULL); + if (s != OBJNULL) { + intern_flag = INTERNAL; + return s; + } + for (ul=p->pack.uses; CONSP(ul); ul = CDR(ul)) { + s = gethash_safe(name, CAR(ul)->pack.external, OBJNULL); + if (s != OBJNULL) { + intern_flag = INHERITED; + return s; + } + } +RETURN: + intern_flag = 0; + return(Cnil); +} + +static void +delete_eq(cl_object x, cl_object *lp) +{ + for (; CONSP(*lp); lp = &CDR((*lp))) + if (CAR((*lp)) == x) { + *lp = CDR((*lp)); + return; + } +} + +bool +unintern(cl_object s, cl_object p) +{ + cl_object x, y, l, hash; + + assert_type_symbol(s); + p = coerce_to_package(p); + hash = p->pack.internal; + x = gethash_safe(s->symbol.name, hash, OBJNULL); + if (x == s) { + if (member_eq(s, p->pack.shadowings)) + goto L; + goto UNINTERN; + } + hash = p->pack.external; + x = gethash_safe(s->symbol.name, hash, OBJNULL); + if (x == s) { + if (member_eq(s, p->pack.shadowings)) + goto L; + goto UNINTERN; + } + return(FALSE); + +L: + x = OBJNULL; + for (l = p->pack.uses; CONSP(l); l = CDR(l)) { + y = gethash_safe(s->symbol.name, CAR(l)->pack.external, OBJNULL); + if (y != OBJNULL) { + if (x == OBJNULL) + x = y; + else if (x != y) +FEerror("Cannot unintern the shadowing symbol ~S~%\ +from ~S,~%\ +because ~S and ~S will cause~%\ +a name conflict.", 4, s, p, x, y); + } + } + delete_eq(s, &p->pack.shadowings); + +UNINTERN: + remhash(s->symbol.name, hash); + if (s->symbol.hpack == p) + s->symbol.hpack = Cnil; + if (s->symbol.stype != stp_ordinary) + uninterned_list = CONS(s, uninterned_list); + return(TRUE); +} + +void +export(cl_object s, cl_object p) +{ + cl_object x, l, hash = OBJNULL; +BEGIN: + assert_type_symbol(s); + p = coerce_to_package(p); + x = find_symbol(s, p); + if (!intern_flag) + FEerror("The symbol ~S is not accessible from ~S.", 2, + s, p); + if (x != s) { + import(s, p); /* signals an error */ + goto BEGIN; + } + if (intern_flag == EXTERNAL) + return; + if (intern_flag == INTERNAL) + hash = p->pack.internal; + for (l = p->pack.usedby; CONSP(l); l = CDR(l)) { + x = find_symbol(s, CAR(l)); + if (intern_flag && s != x && + !member_eq(x, CAR(l)->pack.shadowings)) +FEerror("Cannot export the symbol ~S~%\ +from ~S,~%\ +because it will cause a name conflict~%\ +in ~S.", 3, s, p, CAR(l)); + } + if (hash != OBJNULL) + remhash(s->symbol.name, hash); + sethash(s->symbol.name, p->pack.external, s); +} + +void +delete_package(cl_object p) +{ + cl_object hash, list; + cl_index i; + + p = coerce_to_package(p); + if (p == lisp_package || p == keyword_package) + FEerror("Cannot remove package ~S", 1, p->pack.name); + for (list = p->pack.uses; !endp(list); list = CDR(list)) + unuse_package(CAR(list), p); + for (list = p->pack.usedby; !endp(list); list = CDR(list)) + unuse_package(p, CAR(list)); + for (hash = p->pack.internal, i = 0; i < hash->hash.size; i++) + if (hash->hash.data[i].key != OBJNULL) + unintern(hash->hash.data[i].value, p); + for (hash = p->pack.external, i = 0; i < hash->hash.size; i++) + if (hash->hash.data[i].key != OBJNULL) + unintern(hash->hash.data[i].value, p); + delete_eq(p, &package_list); + p->pack.shadowings = Cnil; + p->pack.internal = OBJNULL; + p->pack.external = OBJNULL; +} + +void +unexport(cl_object s, cl_object p) +{ + cl_object x; + + if (p == keyword_package) + FEerror("Cannot unexport a symbol from the keyword.", 0); + assert_type_symbol(s); + p = coerce_to_package(p); + x = find_symbol(s, p); + if (intern_flag != EXTERNAL || x != s) + /* According to ANSI & Cltl, internal symbols are + ignored in unexport */ + return; + remhash(s->symbol.name, p->pack.external); + sethash(s->symbol.name, p->pack.internal, s); +} + +void +import(cl_object s, cl_object p) +{ + cl_object x; + + assert_type_symbol(s); + p = coerce_to_package(p); + x = find_symbol(s, p); + if (intern_flag) { + if (x != s) + FEerror("Cannot import the symbol ~S~%\ +from ~S,~%\ +because there is already a symbol with the same name~%\ +in the package.", 2, s, p); + if (intern_flag == INTERNAL || intern_flag == EXTERNAL) + return; + } + sethash(s->symbol.name, p->pack.internal, s); + if (Null(s->symbol.hpack)) + s->symbol.hpack = p; +} + +void +shadowing_import(cl_object s, cl_object p) +{ + cl_object x; + + assert_type_symbol(s); + p = coerce_to_package(p); + x = find_symbol(s, p); + if (intern_flag && intern_flag != INHERITED) { + if (x == s) { + if (!member_eq(x, p->pack.shadowings)) + p->pack.shadowings + = CONS(x, p->pack.shadowings); + return; + } + if(member_eq(x, p->pack.shadowings)) + delete_eq(x, &p->pack.shadowings); + if (intern_flag == INTERNAL) + remhash(x->symbol.name, p->pack.internal); + else + remhash(x->symbol.name, p->pack.external); + if (x->symbol.hpack == p) + x->symbol.hpack = Cnil; + if (x->symbol.stype != stp_ordinary) + uninterned_list = CONS(x, uninterned_list); + } + p->pack.shadowings = CONS(s, p->pack.shadowings); + sethash(s->symbol.name, p->pack.internal, s); +} + +void +shadow(cl_object s, cl_object p) +{ + cl_object x; + + assert_type_symbol(s); + p = coerce_to_package(p); + x = find_symbol(s, p); + if (intern_flag != INTERNAL && intern_flag != EXTERNAL) { + x = make_symbol(s); + sethash(x->symbol.name, p->pack.internal, x); + x->symbol.hpack = p; + } + p->pack.shadowings = CONS(x, p->pack.shadowings); +} + +void +use_package(cl_object x, cl_object p) +{ + struct hashtable_entry *hash_entries; + cl_index i, hash_length; + + x = coerce_to_package(x); + if (x == keyword_package) + FEerror("Cannot use keyword package.", 0); + p = coerce_to_package(p); + if (p == keyword_package) + FEerror("Cannot use in keyword package.", 0); + if (p == x) + return; + if (member_eq(x, p->pack.uses)) + return; + hash_entries = x->pack.external->hash.data; + hash_length = x->pack.external->hash.size; + for (i = 0; i < hash_length; i++) + if (hash_entries[i].key != OBJNULL) { + cl_object here = hash_entries[i].value; + cl_object there = find_symbol(here, p); + if (intern_flag && here != there + && ! member_eq(there, p->pack.shadowings)) +FEerror("Cannot use ~S~%\ +from ~S,~%\ +because ~S and ~S will cause~%\ +a name conflict.", 4, x, p, here, there); + } + p->pack.uses = CONS(x, p->pack.uses); + x->pack.usedby = CONS(p, x->pack.usedby); +} + +void +unuse_package(cl_object x, cl_object p) +{ + x = coerce_to_package(x); + p = coerce_to_package(p); + delete_eq(x, &p->pack.uses); + delete_eq(p, &x->pack.usedby); +} + +@(defun make_package (pack_name + &key nicknames + (use `CONS(lisp_package, Cnil)`)) +@ + /* INV: make_package() performs type checking */ + @(return make_package(pack_name, nicknames, use)) +@) + +@(defun si::select_package (pack_name) + cl_object p; +@ + /* INV: find_package()/in_package() perform type checks */ + p = find_package(pack_name); + if (Null(p)) + FEerror("Package ~s not found", 1, pack_name); + @(return (SYM_VAL(Vpackage) = p)) +@) + +@(defun find_package (p) +@ + @(return find_package(p)) +@) + +@(defun package_name (p) +@ + /* INV: coerce_to_package() performs type checks */ + /* FIXME: name should be a fresh one */ + p = coerce_to_package(p); + @(return p->pack.name) +@) + +@(defun package_nicknames (p) +@ + /* INV: coerce_to_package() type checks */ + /* FIXME: list should be a fresh one */ + p = coerce_to_package(p); + @(return p->pack.nicknames) +@) + +@(defun rename_package (pack new_name &o new_nicknames) +@ + /* INV: rename_package() type checks and coerces pack to package */ + @(return rename_package(pack, new_name, new_nicknames)) +@) + +@(defun package_use_list (p) +@ + /* INV: coerce_to_package() type checks */ + /* FIXME: list should be a fresh one */ + p = coerce_to_package(p); + @(return p->pack.uses) +@) + +@(defun package_used_by_list (p) +@ + /* INV: coerce_to_package() type checks */ + /* FIXME: list should be a fresh one */ + p = coerce_to_package(p); + @(return p->pack.usedby) +@) + +@(defun package_shadowing_symbols (p) +@ + /* INV: coerce_to_package() type checks */ + /* FIXME: list should be a fresh one */ + p = coerce_to_package(p); + @(return p->pack.shadowings) +@) + +@(defun si::package_lock (p t) +@ + /* INV: coerce_to_package() type checks */ + p = coerce_to_package(p); + p->pack.locked = (t != Cnil); + @(return p) +@) + +@(defun list_all_packages () +@ + @(return copy_list(package_list)) +@) + +@(defun intern (strng &optional (p `current_package()`) &aux sym) +@ + sym = intern(strng, p); + if (intern_flag == INTERNAL) + @(return sym Kinternal) + if (intern_flag == EXTERNAL) + @(return sym Kexternal) + if (intern_flag == INHERITED) + @(return sym Kinherited) + @(return sym Cnil) +@) + +@(defun find_symbol (strng &optional (p `current_package()`)) + cl_object x; +@ + x = find_symbol(strng, p); + if (intern_flag == INTERNAL) + @(return x Kinternal) + if (intern_flag == EXTERNAL) + @(return x Kexternal) + if (intern_flag == INHERITED) + @(return x Kinherited) + @(return Cnil Cnil) +@) + +@(defun unintern (symbl &optional (p `current_package()`)) +@ + @(return `unintern(symbl, p) ? Ct : Cnil`) +@) + +@(defun export (symbols &o (pack `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(symbols)) { + case t_symbol: + if (Null(symbols)) + break; + export(symbols, pack); + break; + + case t_cons: + pack = coerce_to_package(pack); /* Saves time */ + for (l = symbols; !endp(l); l = CDR(l)) + export(CAR(l), pack); + break; + + default: + assert_type_symbol(symbols); + goto BEGIN; + } + @(return Ct) +@) + +@(defun unexport (symbols &o (pack `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(symbols)) { + case t_symbol: + if (Null(symbols)) + break; + unexport(symbols, pack); + break; + + case t_cons: + pack = coerce_to_package(pack); /* Saves time */ + for (l = symbols; !endp(l); l = CDR(l)) + unexport(CAR(l), pack); + break; + + default: + assert_type_symbol(symbols); + goto BEGIN; + } + @(return Ct) +@) + +@(defun import (symbols &o (pack `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(symbols)) { + case t_symbol: + if (Null(symbols)) + break; + import(symbols, pack); + break; + + case t_cons: + pack = coerce_to_package(pack); /* Saves time */ + for (l = symbols; !endp(l); l = CDR(l)) + import(CAR(l), pack); + break; + + default: + assert_type_symbol(symbols); + goto BEGIN; + } + @(return Ct) +@) + +@(defun shadowing_import (symbols &o (pack `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(symbols)) { + case t_symbol: + if (Null(symbols)) + break; + shadowing_import(symbols, pack); + break; + + case t_cons: + pack = coerce_to_package(pack); /* Saves time */ + for (l = symbols; !endp(l); l = CDR(l)) + shadowing_import(CAR(l), pack); + break; + + default: + assert_type_symbol(symbols); + goto BEGIN; + } + @(return Ct) +@) + +@(defun shadow (symbols &o (pack `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(symbols)) { + case t_symbol: + if (Null(symbols)) + break; + shadow(symbols, pack); + break; + + case t_cons: + pack = coerce_to_package(pack); /* Saves time */ + for (l = symbols; !endp(l); l = CDR(l)) + shadow(CAR(l), pack); + break; + + default: + assert_type_symbol(symbols); + goto BEGIN; + } + @(return Ct) +@) + +@(defun use_package (pack &o (pa `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(pack)) { + case t_symbol: + if (Null(pack)) + break; + case t_string: + case t_package: + use_package(pack, pa); + break; + + case t_cons: + pa = coerce_to_package(pa); /* Saves time */ + for (l = pack; !endp(l); l = CDR(l)) + use_package(CAR(l), pa); + break; + + default: + assert_type_package(pack); + goto BEGIN; + } + @(return Ct) +@) + +@(defun unuse_package (pack &o (pa `current_package()`)) + cl_object l; +@ +BEGIN: + switch (type_of(pack)) { + case t_symbol: + if (Null(pack)) + break; + + case t_string: + case t_package: + unuse_package(pack, pa); + break; + + case t_cons: + pa = coerce_to_package(pa); + for (l = pack; !endp(l); l = CDR(l)) + unuse_package(CAR(l), pa); + break; + + default: + assert_type_package(pack); + goto BEGIN; + } + @(return Ct) +@) + +@(defun si::package_internal (p index) + cl_fixnum j; + cl_object hash; +@ + p = coerce_to_package(p); + hash = p->pack.internal; + if (!FIXNUMP(index) || (j = fix(index)) < 0 || j >= hash->hash.size) + FEerror("~S is an illegal index to a package hashtable.", + 1, index); + @(return ((hash->hash.data[j].key != OBJNULL)? + hash->hash.data[j].value : MAKE_FIXNUM(1))) +@) + +@(defun si::package_external (p index) + cl_fixnum j; + cl_object hash; +@ + p = coerce_to_package(p); + hash = p->pack.external; + if (!FIXNUMP(index) || (j = fix(index)) < 0 || j >= hash->hash.size) + FEerror("~S is an illegal index to a package hashtable.", + 1, index); + @(return ((hash->hash.data[j].key != OBJNULL)? + hash->hash.data[j].value : MAKE_FIXNUM(1))) +@) + +@(defun si::package_size (p) +@ + assert_type_package(p); + @(return MAKE_FIXNUM(p->pack.external->hash.size) + MAKE_FIXNUM(p->pack.internal->hash.size)) +@) + +@(defun delete_package (p) +@ + delete_package(p); +@) + +void +init_package(void) +{ + register_root(&package_list); + register_root(&uninterned_list); + + lisp_package = make_package(make_simple_string("COMMON-LISP"), + CONS(make_simple_string("CL"), + CONS(make_simple_string("LISP"),Cnil)), + Cnil); + register_root(&lisp_package); + user_package = make_package(make_simple_string("COMMON-LISP-USER"), + CONS(make_simple_string("CL-USER"), + CONS(make_simple_string("USER"),Cnil)), + CONS(lisp_package, Cnil)); + register_root(&user_package); + keyword_package = make_package(make_simple_string("KEYWORD"), + Cnil, Cnil); + register_root(&keyword_package); + system_package = make_package(make_simple_string("SI"), + CONS(make_simple_string("SYSTEM"), + CONS(make_simple_string("SYS"), + Cnil)), + CONS(lisp_package, Cnil)); + register_root(&system_package); +#ifdef CLOS + clos_package = make_package(make_simple_string("CLOS"), + Cnil, + CONS(lisp_package, Cnil)); + register_root(&clos_package); +#endif +#ifdef TK + tk_package = make_package(make_simple_string("TK"), + Cnil, + CONS(lisp_package, Cnil)); + register_root(&tk_package); +#endif + + Cnil->symbol.hpack = lisp_package; + import(Cnil, lisp_package); + export(Cnil, lisp_package); + + Ct->symbol.hpack = lisp_package; + import(Ct, lisp_package); + export(Ct, lisp_package); + + /* There is no need to enter a package as a mark origin. */ + + Vpackage = make_special("*PACKAGE*", lisp_package); +} diff --git a/src/c/pathname.d b/src/c/pathname.d new file mode 100644 index 000000000..b9ac03db6 --- /dev/null +++ b/src/c/pathname.d @@ -0,0 +1,1186 @@ +/* + pathname.d -- Pathnames. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +/* + O.S. DEPENDENT + + This file contains those functions that interpret namestrings. +*/ + +#include "ecls.h" +#include + +/******************************* EXPORTS ******************************/ + +cl_object Vdefault_pathname_defaults; +cl_object Kwild; +cl_object Kwild_inferiors; +cl_object Knewest; + +/******************************* ------- ******************************/ + +cl_object Khost; +cl_object Kdevice; +cl_object Kdirectory; +cl_object Kname; +cl_object Ktype; +cl_object Kversion; +cl_object Kdefaults; + +cl_object Kabsolute; +cl_object Krelative; +cl_object Kup; + +static cl_object pathname_translations = Cnil; + +static void +error_directory(cl_object d) { + FEerror("make-pathname: ~A is not a valid directory", 1, d); +} + +cl_object +make_pathname(cl_object host, cl_object device, cl_object directory, + cl_object name, cl_object type, cl_object version) +{ + cl_object x; + + if (!endp(directory) && + CAR(directory) != Kabsolute && + CAR(directory) != Krelative) + error_directory(directory); + x = alloc_object(t_pathname); + x->pathname.logical = FALSE; + x->pathname.host = host; + x->pathname.device = device; + x->pathname.directory = directory; + x->pathname.name = name; + x->pathname.type = type; + x->pathname.version = version; + return(x); +} + + +static cl_object +tilde_expand(cl_object directory) +{ + cl_object head, prefix; + + if (endp(directory)) + goto RET; + /* If path is absolute or null, we have nothing + to expand */ + head = CAR(directory); + if (head == Kabsolute) + goto RET; + /* If path is relative and not empty, we search + for heading tilde */ + if (head != Krelative) + error_directory(directory); + head = CADR(directory); + if (type_of(head) != t_string) + goto RET; + if (head->string.fillp == 0 || head->string.self[0] != '~') + goto RET; + prefix = homedir_pathname(head)->pathname.directory; + directory = append(prefix, CDDR(directory)); + RET: + return directory; +} + +#define WORD_INCLUDE_DELIM 1 +#define WORD_ALLOW_ASTERISK 2 +#define WORD_EMPTY_IS_NIL 4 +#define WORD_LOGICAL 8 + +static cl_object +make_one(const char *s, cl_index end) +{ + cl_object x = alloc_simple_string(end); + x->string.self = alloc(end+1); + memcpy(x->string.self, s, end); + x->string.self[end] = '\0'; + return(x); +} + +/* + * Parses a word from string `S' until either: + * 1) character `DELIM' is found + * 2) end of string is reached + * 3) a non valid character is found + * Output is either + * 1) :error in case (3) above + * 2) :wild, :wild-inferiors, :up + * 3) "" or Cnil when word has no elements + * 5) A non empty string + */ +static cl_object +parse_word(const char *s, char delim, int flags, cl_index start, cl_index end, + cl_index *end_of_word) +{ + volatile cl_index i, j; + for (i = j = start; i < end && s[i] != delim; i++) { + char c = s[i]; + bool valid_char; + if (c == '*') { + if (!(flags & WORD_ALLOW_ASTERISK)) + valid_char = FALSE; /* Asterisks not allowed in this word */ + else if (i > start && s[i-1] == '*' && end > start + 2) + valid_char = FALSE; /* "**" surrounded by other characters! */ + else + valid_char = TRUE; /* single "*" */ + } +#if 0 + else if (flags & WORD_LOGICAL) + valid_char = is_upper(c) || is_digit(c) || c == '-'; +#endif + else + valid_char = c != 0; + if (!valid_char) { + *end_of_word = start; + return Kerror; + } + } + if (i < end) + *end_of_word = i+1; + else { + *end_of_word = end; + if (flags & WORD_INCLUDE_DELIM) { + *end_of_word = start; + return Cnil; + } + } + s += j; + switch(i-j) { + case 0: + if (flags & WORD_EMPTY_IS_NIL) + return Cnil; + return null_string; + case 1: + if (s[0] == '*') + return Kwild; + break; + case 2: + if (s[0] == '*' && s[1] == '*') + /* :wild-inferiors not supported in pathnames */ + return Kerror; + if (!(flags & WORD_LOGICAL) && s[0] == '.' && s[1] == '.') + return Kup; + break; + } + return make_one(s, i-j); +} + +/* + * Parses a logical or physical directory tree. Output is always a + * list of valid directory components, which may be just NIL. + * + * INV: When parsing of directory components has failed, a valid list + * is also returned, and it will be later in the parsing of + * pathname-name or pathname-type when the same error is detected. + */ + +static cl_object +parse_directories(const char *s, int flags, cl_index start, cl_index end, + cl_index *end_of_dir) +{ + cl_index i, j; + cl_object path = Cnil; + cl_object *plast = &path; + char delim = (flags & WORD_LOGICAL) ? ';' : '/'; + + flags |= WORD_INCLUDE_DELIM | WORD_ALLOW_ASTERISK; + *end_of_dir = start; + for (i = j = start; i < end; j = i) { + cl_object word = parse_word(s, delim, flags, j, end, &i); + if (word == Kerror || word == Cnil) + break; + if (word == null_string) { /* just "/" or ";" */ + if (j != start) { + if (flags & WORD_LOGICAL) + return Kerror; + continue; + } + word = (flags & WORD_LOGICAL) ? Krelative : Kabsolute; + } + *end_of_dir = i; + plast = &CDR(*plast = CONS(word, Cnil)); + } + return path; +} + +bool +logical_hostname_p(cl_object host) +{ + if (type_of(host) != t_string) + return FALSE; + return assoc(host, pathname_translations) != Cnil; +} + +/* + * Parses a lisp namestring until the whole substring is parsed or an + * error is found. It returns a valid pathname or NIL, plus the place + * where parsing ended in *END_OF_PARSING. + * + * The rules are as follows: + * + * 1) If a hostname is supplied it determines whether the namestring + * will be parsed as logical or as physical. + * + * 2) If no hostname is supplied, first it tries parsing using logical + * pathname rules and, if no logical hostname is found, then it + * tries the physical pathname format. + * + * 3) Logical pathname syntax: + * [logical-hostname:][;][logical-directory-component;][pathname-name][.pathname-type] + * + * 4) Physical pathname syntax: + * [device:][[//hostname]/][directory-component/]*[pathname-name][.pathname-type] + * + * logical-hostname, device, hostname = word + * logical-directory-component = word | wildcard-word + * directory-component = word | wildcard-word | '..' | '.' + * pathname-name, pathname-type = word | wildcard-word | "" + * + */ +cl_object +parse_namestring(const char *s, cl_index start, cl_index end, cl_index *ep, + cl_object default_host) +{ + cl_object host, device, path, name, type; + bool logical; + + /* We first try parsing as logical-pathname. In case of + * failure, physical-pathname parsing is performed only when + * there is no supplied *logical* host name. All other failures + * result in Cnil as output. + */ + host = parse_word(s, ':', WORD_LOGICAL | WORD_INCLUDE_DELIM, start, end, ep); + if (default_host != Cnil) { + if (host == Cnil || host == Kerror) + host = default_host; + else if (!equal(default_host, host)) + return Cnil; + } + if (!logical_hostname_p(host)) + goto physical; + /* + * Logical pathname format: + * [logical-hostname:][;][logical-directory-component;][pathname-name][.pathname-type] + */ + logical = TRUE; + device = Cnil; + path = parse_directories(s, WORD_LOGICAL, *ep, end, ep); + if (path == Kerror) + return Cnil; + if (!endp(path) && CAR(path) != Krelative) + path = CONS(Kabsolute, path); + name = parse_word(s, '.', WORD_LOGICAL | WORD_ALLOW_ASTERISK | WORD_EMPTY_IS_NIL, *ep, end, ep); + type = parse_word(s, '\0', WORD_LOGICAL | WORD_ALLOW_ASTERISK | WORD_EMPTY_IS_NIL, *ep, end, ep); + if (type == Kerror) + return Cnil; + goto make_it; + physical: + /* + * Physical pathname format: + * [device:][[//hostname]/][directory-component/]*[pathname-name][.pathname-type] + */ + logical = FALSE; + device = parse_word(s, ':', WORD_INCLUDE_DELIM | WORD_EMPTY_IS_NIL, + start, end, ep); + if (device == Kerror) + device = Cnil; + else if (device != Cnil) { + if (type_of(device) != t_string) + return Cnil; + if (strcmp(device->string.self, "file") == 0) + device = Cnil; + } + start = *ep; + if (start <= end - 2 && s[start] == '/' && s[start+1] == '/') + host = parse_word(s, '/', WORD_EMPTY_IS_NIL, start, end, ep); + else + host = Cnil; + if (host == Kerror) + host = Cnil; + else if (host != Cnil) { + if (type_of(host) != t_string || !equal(host, default_host)) + return Cnil; + } + path = parse_directories(s, 0, *ep, end, ep); + if (path == Kerror) + return Cnil; + if (!endp(path)) { + if (CAR(path) == Kabsolute) { + /* According to ANSI CL, "/.." is erroneous */ + if (cadr(path) == Kup) + return Cnil; + } else { + /* If path is relative and we got here, then it + has no :RELATIVE/:ABSOLUTE in front of it and we add one. + Pathnames with hostnames are always absolute. + */ + path = CONS(host == Cnil? Krelative : Kabsolute, path); + path = tilde_expand(path); + } + } + name = parse_word(s, '.', WORD_ALLOW_ASTERISK | WORD_EMPTY_IS_NIL, *ep, + end, ep); + type = parse_word(s, '\0', WORD_ALLOW_ASTERISK | WORD_EMPTY_IS_NIL, *ep, + end, ep); + if (type == Kerror) + return Cnil; + make_it: + if (*ep >= end) *ep = end; + path = make_pathname(host, device, path, name, type, Cnil); + path->pathname.logical = logical; + return path; +} + +cl_object +coerce_to_pathname(cl_object x) +{ + cl_object y; + cl_index e; + +L: + switch (type_of(x)) { + case t_string: + /* !!!!! Bug Fix. NLG */ + y = parse_namestring(x->string.self, 0, x->string.fillp, &e,Cnil); + if (y == Cnil || e != x->string.fillp) + FEerror("~S is not a valid pathname string", 1, x); + return(y); + + case t_pathname: + return(x); + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_closed: + case smm_input: + case smm_output: + case smm_probe: + case smm_io: + x = x->stream.object1; + /* + The file was stored in stream.object1. + See open. + */ + goto L; + + case smm_synonym: + x = symbol_value(x->stream.object0); + goto L; + default: + } + default: + FEerror("~S cannot be coerced to a pathname.", 1, x); + } +} + +cl_object +coerce_to_file_pathname(cl_object pathname) +{ + pathname = coerce_to_physical_pathname(pathname); + if (pathname->pathname.device != Cnil) + FEerror("Device ~S not yet supported.", 1, + pathname->pathname.device); + if (pathname->pathname.host != Cnil) + FEerror("Access to remote files not yet supported.", 0); + return pathname; +} + +static cl_object translate_logical_pathname(cl_object x); + +cl_object +coerce_to_physical_pathname(cl_object x) +{ + x = coerce_to_pathname(x); + if (x->pathname.logical) + return translate_logical_pathname(x); + return x; +} + +cl_object +coerce_to_filename(cl_object pathname) +{ + cl_object namestring; + + pathname = coerce_to_file_pathname(pathname); + namestring = coerce_to_namestring(pathname); + if (namestring->string.fillp >= MAXPATHLEN - 16) + FEerror("Too long filename: ~S.", 1, namestring); + return namestring; +} + +cl_object +default_device(cl_object host) +{ + return Cnil; +} + +cl_object +merge_pathnames(cl_object path, cl_object defaults, cl_object default_version) +{ + cl_object host, device, directory, name, type, version; + + defaults = coerce_to_pathname(defaults); + if (type_of(path) == t_string) { + cl_index foo; + cl_object aux = parse_namestring(path->string.self, 0, + path->string.fillp, &foo, + default_version->pathname.host); + if (aux != Cnil) path = aux; + } + if (type_of(path) != t_pathname) + path = coerce_to_pathname(path); + if (Null(path->pathname.host)) + host = defaults->pathname.host; + else + host = path->pathname.host; + if (Null(path->pathname.device)) + if (Null(path->pathname.host)) + device = defaults->pathname.device; + else if (path->pathname.host == defaults->pathname.host) + device = defaults->pathname.device; + else + device = default_device(path->pathname.host); + else + device = path->pathname.device; + if (Null(path->pathname.directory)) + directory = defaults->pathname.directory; + else if (CAR(path->pathname.directory) == Kabsolute) + directory = path->pathname.directory; + else if (!Null(defaults->pathname.directory)) + directory = append(defaults->pathname.directory, + CDR(path->pathname.directory)); + else + directory = path->pathname.directory; + if (Null(path->pathname.name)) + name = defaults->pathname.name; + else + name = path->pathname.name; + if (Null(path->pathname.type)) + type = defaults->pathname.type; + else + type = path->pathname.type; + version = Cnil; + /* + In this implementation, version is not considered + */ + defaults = make_pathname(host, device, directory, name, type, version); + defaults->pathname.logical = path->pathname.logical; + return defaults; +} + +static void +push_c_string(cl_object buffer, const char *s, cl_index length) +{ + cl_index fillp = buffer->string.fillp; + cl_index dim = buffer->string.dim; + char *dest = buffer->string.self; + + if (type_of(buffer) != t_string) + internal_error("push_c_string"); + for (; length; length--, s++) { + dest[fillp++] = *s; + if (fillp >= dim) { + char *new_dest = alloc_atomic(dim += 32); + memcpy(new_dest, dest, fillp); + buffer->string.dim = dim; + buffer->string.self = new_dest; + dest = new_dest; + } + } + buffer->string.fillp = fillp; +} + +static void +push_string(cl_object buffer, cl_object string) +{ + string = coerce_to_string_designator(string); + push_c_string(buffer, string->string.self, string->string.fillp); +} + +/* + namestring(x) converts a pathname to a namestring. +*/ +cl_object +namestring(cl_object x) +{ + cl_object l, y; + bool logical; + cl_object buffer, host; + + buffer = cl_token; + buffer->string.fillp = 0; + logical = x->pathname.logical; + host = x->pathname.host; + if (logical) { + if (host != Cnil) { + push_string(buffer, host); + push_c_string(buffer, ":", 1); + } + } else { + if ((y = x->pathname.device) != Cnil) { + push_string(buffer, y); + push_c_string(buffer, ":", 1); + } + if (host != Cnil) { + if (y == Cnil) + push_c_string(buffer, "file:", 5); + push_c_string(buffer, "//", 2); + push_string(buffer, host); + } + } + l = x->pathname.directory; + if (endp(l)) + goto L; + y = CAR(l); + if (y == Krelative) { + if (logical) + push_c_string(buffer, ":", 1); + } else if (y == Kabsolute) { + if (!logical) + push_c_string(buffer, "/", 1); + } else + FEerror("namestring: ~A is not a valid directory list",1, l); + l = CDR(l); + for (; !endp(l); l = CDR(l)) { + y = CAR(l); + if (y == Kup) { + push_c_string(buffer, "..", 2); + } else if (y == Kwild) { + push_c_string(buffer, "*", 1); + } else if (y == Kwild_inferiors) { + push_c_string(buffer, "**", 2); + } else { + push_string(buffer, y); + } + push_c_string(buffer, logical? ";" : "/", 1); + } +L: + if (Null(y = x->pathname.name)) + goto M; + if (y == Kwild) { + push_c_string(buffer, "*", 1); + goto M; + } + if (type_of(y) != t_string) + FEerror("~S is an illegal pathname name.", 1, y); + push_string(buffer, y); +M: + if (Null(y = x->pathname.type)) + goto N; + if (y == Kwild) { + push_c_string(buffer, ".*", 2); + goto N; + } + if (type_of(y) != t_string) + FEerror("~S is an illegal pathname type.", 1, y); + push_c_string(buffer, ".", 1); + push_string(buffer, y); +N: + return(copy_simple_string(cl_token)); +} + +cl_object +coerce_to_namestring(cl_object x) +{ + cl_object y; +L: + switch (type_of(x)) { + case t_string: + if (x->string.self[0] != '~') + return(x); + /* added by E. Wang */ + return(namestring(coerce_to_pathname(x))); + + case t_pathname: + return(namestring(x)); + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_input: + case smm_output: + case smm_probe: + case smm_io: + x = x->stream.object1; + /* + The file was stored in stream.object1. + See open. + */ + goto L; + + case smm_synonym: + x = symbol_value(x->stream.object0); + goto L; + + default: + goto CANNOT_COERCE; + } + + default: + CANNOT_COERCE: + FEerror("~S cannot be coerced to a namestring.", 1, x); + } +} + +@(defun pathname (name) +@ /* INV: coerce_to_pathname() checks types */ + @(return coerce_to_pathname(name)) +@) + +@(defun parse_namestring (thing + &o host + (defaults symbol_value(Vdefault_pathname_defaults)) + &k (start MAKE_FIXNUM(0)) end junk_allowed + &a x y) + cl_index s, e, ee; +@ + /* INV: coerce_to_pathname() checks types */ + /* defaults is ignored */ + x = thing; +L: + switch (type_of(x)) { + case t_string: + get_string_start_end(x, start, end, &s, &e); + y = parse_namestring(x->string.self, s, e - s, &ee, host); + if (Null(junk_allowed)) { + if (y == Cnil || ee != e - s) + FEerror("Cannot parse the namestring ~S~%\nfrom ~S to ~S.", + 3, x, start, end); + } else { + if (y == Cnil) + @(return Cnil `MAKE_FIXNUM(s + ee)`) + } + if (logical_hostname_p(host) && y != Cnil && !y->pathname.logical) { + if (Null(junk_allowed)) + FEerror("A logical pathname was expected instead of ~S", 1, thing); + else + @(return Cnil `MAKE_FIXNUM(s + ee)`); + } + start = MAKE_FIXNUM(s + ee); + break; + + case t_pathname: + y = x; + break; + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_input: + case smm_output: + case smm_probe: + case smm_io: + x = x->stream.object1; + /* + The file was stored in stream.object1. + See open. + */ + goto L; + + case smm_synonym: + x = symbol_value(x->stream.object0); + goto L; + + default: + goto CANNOT_PARSE; + } + + default: + CANNOT_PARSE: + FEerror("Object ~S does not contain a valid namestring.", 1, x); + } + @(return y start) +@) + +@(defun merge_pathnames (path + &o (defaults symbol_value(Vdefault_pathname_defaults)) + (default_version Knewest)) +@ + /* INV: coerce_to_pathname() checks types */ + path = coerce_to_pathname(path); + defaults = coerce_to_pathname(defaults); + @(return merge_pathnames(path, defaults, default_version)) +@) + +@(defun make_pathname (&key host device directory name + type version defaults + &aux x) +@ + if (Null(defaults)) { + defaults + = symbol_value(Vdefault_pathname_defaults); + defaults = coerce_to_pathname(defaults); + defaults + = make_pathname(defaults->pathname.host, + Cnil, Cnil, Cnil, Cnil, Cnil); + } else + defaults = coerce_to_pathname(defaults); + x = make_pathname(host, device, directory, name, type, version); + x = merge_pathnames(x, defaults, Cnil); + @(return x) +@) + +@(defun pathnamep (pname) +@ + @(return ((type_of(pname) == t_pathname)? Ct : Cnil)) +@) + +@(defun si::logical_pathname_p (pname) +@ + @(return ((type_of(pname) == t_pathname && pname->pathname.logical)? + Ct : Cnil)) +@) + +@(defun pathname_host (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.host) +@) + +@(defun pathname_device (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.device) +@) + +@(defun pathname_directory (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.directory) +@) + +@(defun pathname_name (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.name) +@) + +@(defun pathname_type (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.type) +@) + +@(defun pathname_version (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return pname->pathname.version) +@) + +@(defun namestring (pname) +@ + /* INV: coerce_to_pathname() checks types */ + @(return coerce_to_namestring(pname)) +@) + +@(defun file_namestring (pname) +@ + /* INV: coerce_to_filename() checks types */ + pname = coerce_to_filename(pname); + @(return namestring(make_pathname(Cnil, Cnil, Cnil, + pname->pathname.name, + pname->pathname.type, + pname->pathname.version))) +@) + +@(defun directory_namestring (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + @(return namestring(make_pathname(Cnil, Cnil, + pname->pathname.directory, + Cnil, Cnil, Cnil))) +@) + +@(defun host_namestring (pname) +@ + /* INV: coerce_to_pathname() checks types */ + pname = coerce_to_pathname(pname); + pname = pname->pathname.host; + if (Null(pname) || pname == Kwild) + pname = null_string; + @(return pname) +@) + +@(defun enough_namestring (path + &o (defaults symbol_value(Vdefault_pathname_defaults))) + cl_object newpath; +@ + /* INV: coerce_to_pathname() checks types */ + defaults = coerce_to_pathname(defaults); + path = coerce_to_pathname(path); + newpath + = make_pathname(equalp(path->pathname.host, defaults->pathname.host) ? + Cnil : path->pathname.host, + equalp(path->pathname.device, + defaults->pathname.device) ? + Cnil : path->pathname.device, + equalp(path->pathname.directory, + defaults->pathname.directory) ? + Cnil : path->pathname.directory, + equalp(path->pathname.name, defaults->pathname.name) ? + Cnil : path->pathname.name, + equalp(path->pathname.type, defaults->pathname.type) ? + Cnil : path->pathname.type, + equalp(path->pathname.version, + defaults->pathname.version) ? + Cnil : path->pathname.version); + newpath->pathname.logical = path->pathname.logical; + @(return namestring(newpath)) +@) + +/* --------------- PATHNAME MATCHING ------------------ */ + +static bool path_item_match(cl_object a, cl_object mask); + +static bool +do_path_item_match(const char *s, const char *p) { + const char *next; + while (*s) { + if (*p == '*') { + /* Match any group of characters */ + next = p+1; + while (*s && *s != *next) s++; + if (do_path_item_match(s,next)) + return TRUE; + /* starts back from the '*' */ + if (!*s) + return FALSE; + s++; + } else if (*s != *p) + return FALSE; + else + s++, p++; + } + return (*p == 0); +} + +static bool +path_item_match(cl_object a, cl_object mask) { + if (mask == Kwild || mask == Cnil) + return TRUE; + if (type_of(a) != t_string) + return (a == mask); + if (type_of(mask) != t_string) + FEerror("~S is not supported as mask for pathname-match-p", 1, mask); + return do_path_item_match(a->string.self, mask->string.self); +} + +bool +pathname_match_p(cl_object path, cl_object mask) +{ + cl_object a, b; + path = coerce_to_pathname(path); + mask = coerce_to_pathname(mask); + if (path->pathname.logical != mask->pathname.logical) + return FALSE; +#if 0 + if (!path_item_match(path->pathname.host, mask->pathname.host)) + return FALSE; +#endif + a = path->pathname.directory; + b = mask->pathname.directory; + while (!endp(a)) { + if (endp(b)) + /* Directory tree lengths do not match */ + return FALSE; + if (!path_item_match(CAR(a), CAR(b))) + return FALSE; + a = CDR(a); + b = CDR(b); + } + if (a != b) + /* Directory tree lengths do not match */ + return FALSE; + if (!path_item_match(path->pathname.name, mask->pathname.name)) + return FALSE; + if (!path_item_match(path->pathname.type, mask->pathname.type)) + return FALSE; + if (!path_item_match(path->pathname.version, mask->pathname.version)) + return FALSE; + return TRUE; +} + +@(defun pathname_match_p (path mask) +@ + @(return (pathname_match_p(path, mask)? Ct : Cnil)) +@) + +/* --------------- PATHNAME TRANSLATIONS ------------------ */ + +static cl_object +coerce_to_from_pathname(cl_object x, cl_object host) +{ + cl_object y; + cl_index e; + + switch (type_of(x)) { + case t_string: + /* !!!!! Bug Fix. NLG */ + y = parse_namestring(x->string.self, 0, x->string.fillp, &e, host); + if (y == Cnil || e != x->string.fillp) + FEerror("~S is not a valid pathname string", 1, x); + x = y; + case t_pathname: + if (x->pathname.logical) + return x; + default: + return Cnil; + } +} + +@(defun si::pathname_translations (host &optional (set OBJNULL)) + cl_index aux; + cl_object pair, l; +@ + /* Check that host is a valid host name */ + assert_type_string(host); + aux = host->string.fillp; + parse_word(host->string.self, '\0', WORD_LOGICAL, 0, aux, &aux); + if (aux != host->string.fillp) + FEerror("Wrong host syntax ~S", 1, host); + + /* Find its translation list */ + pair = assoc(host, pathname_translations); + if (set == OBJNULL) + @(return ((pair == Cnil)? Cnil : CADR(pair))) + + /* Set the new translation list */ + assert_type_list(set); + if (pair == Cnil) { + pair = CONS(host, CONS(Cnil, Cnil)); + pathname_translations = CONS(pair, pathname_translations); + } + for (l = set, set = Cnil; !endp(l); l = CDR(l)) { + cl_object item = CAR(l); + cl_object from = coerce_to_from_pathname(car(item), host); + cl_object to = coerce_to_pathname(cadr(item)); + if (type_of(from) != t_pathname || !from->pathname.logical) + FEerror("~S is not a valid from-pathname translation", 1, from); + if (type_of(to) != t_pathname) + FEerror("~S is not a valid to-pathname translation", 1, from); + set = CONS(CONS(from, CONS(to, Cnil)), set); + } + CADR(pair) = Lreconc(2, set, Cnil); + @(return set) +@) + +static cl_object +find_wilds(cl_object l, cl_object source_item, cl_object match) +{ + const char *a, *b; + cl_index i, j, k, ia, ib; + + if (match == Kwild || match == Cnil) + return CONS(source_item, Cnil); + if (match == Kwild_inferiors) + FEerror(":wild-inferiors not yet supported", 0); + if (type_of(match) != t_string || type_of(source_item) != t_string) { + if (match != source_item) + return Kerror; + return l; + } + a = source_item->string.self; + ia = source_item->string.fillp; + b = match->string.self; + ib = match->string.fillp; + for(i = j = 0; i < ia && j < ib; ) { + if (b[j] == '*') { + for (j++, k = i; k < ia && a[k] != b[j]; k++) + ; + l = CONS(make_one(&a[i], k-i), l); + i = k; + continue; + } + if (a[i] != b[j]) + return Kerror; + i++, j++; + } + if (i < ia || j < ib) + return Kerror; + return l; +} + +static cl_object +copy_wildcards(cl_object *wilds_list, cl_object template) +{ + char *s; + cl_index i, l, j; + bool new_string; + cl_object wilds = *wilds_list; + + if (template == Kwild || template == Cnil) { + if (endp(wilds)) + return Kerror; + template = CAR(wilds); + *wilds_list = CDR(wilds); + return template; + } + if (type_of(template) != t_string) + return template; + + new_string = FALSE; + s = template->string.self; + l = template->string.fillp; + cl_token->string.fillp = 0; + + for (j = i = 0; i < l; ) { + if (s[i] != '*') { + i++; + continue; + } + if (i != j) + push_c_string(cl_token, &s[j], i-j); + new_string = TRUE; + if (endp(wilds)) + return Kerror; + push_string(cl_token, CAR(wilds)); + wilds = CDR(wilds); + j = i++; + } + /* Only create a new string when needed */ + if (new_string) + template = copy_simple_string(cl_token); + *wilds_list = wilds; + return template; +} + +cl_object +translate_pathname(cl_object source, cl_object from, cl_object to) +{ + cl_object wilds, out, a, b, c, d, *pc; + + source = coerce_to_pathname(source); + from = coerce_to_pathname(from); + to = coerce_to_pathname(to); + + if (source->pathname.logical != from->pathname.logical) + goto error; + out = alloc_object(t_pathname); + out->pathname.logical = to->pathname.logical; + + /* Match host names */ + if (!equal(source->pathname.host, from->pathname.host)) + goto error; + out->pathname.host = to->pathname.host; + + /* Match devices */ + if (!equal(source->pathname.device, from->pathname.device)) + goto error; + out->pathname.device = to->pathname.device; + + /* Match directories */ + wilds = Cnil; + a = source->pathname.directory; + b = from->pathname.directory; + while (!endp(a) && !endp(b)) { + wilds = find_wilds(wilds, CAR(a), CAR(b)); + if (wilds == Kerror) goto error; + a = CDR(a); + b = CDR(b); + } + Lreconc(2, wilds, Cnil); + if (a != Cnil || b != Cnil) + goto error; + for (c = Cnil, pc = &c, b = to->pathname.directory; !endp(b); b = CDR(b)) { + d = copy_wildcards(&wilds, CAR(b)); + if (d == Kerror) goto error2; + *pc = CONS(d, Cnil); + pc = &CDR(*pc); + } + if (wilds != Cnil) + goto error2; + out->pathname.directory = c; + + /* Match name */ + wilds = find_wilds(Cnil, source->pathname.name, from->pathname.name); + if (wilds == Kerror) goto error2; + d = copy_wildcards(&wilds, to->pathname.name); + if (d == Kerror || wilds != Cnil) goto error2; + out->pathname.name = d; + + /* Match type */ + wilds = find_wilds(Cnil, source->pathname.type, from->pathname.type); + if (wilds == Kerror) goto error2; + d = copy_wildcards(&wilds, to->pathname.type); + if (d == Kerror || wilds != Cnil) goto error2; + out->pathname.type = d; + + /* Match version */ +#if 0 + wilds = find_wilds(Cnil, source->pathname.version, from->pathname.version); + if (wilds == Kerror) goto error2; + d = copy_wildcards(&wilds, to->pathname.version); + if (d == Kerror || wilds != Cnil) goto error2; + out->pathname.version = d; +#else + out->pathname.version = Cnil; +#endif + return out; + + error: + FEerror("~S is not a specialization of path ~S", 2, source, from); + error2: + FEerror("Number of wildcards in ~S do not match ~S", 2, from, to); +} + +@(defun translate_pathname (source from to) +@ + @(return translate_pathname(source, from, to)) +@) + +static cl_object +translate_logical_pathname(cl_object source) +{ + cl_object l, pair; + source = coerce_to_pathname(source); + if (!source->pathname.logical) + goto error; + begin: + l = siLpathname_translations(1, source->pathname.host, Cnil); + for(; !endp(l); l = CDR(l)) { + pair = CAR(l); + if (pathname_match_p(source, CAR(pair))) { + source = translate_pathname(source, CAR(pair), CADR(pair)); + if (source->pathname.logical) + goto begin; + return source; + } + } + error: + FEerror("~S admits no logical pathname translations", 1, source); +} + +@(defun translate_logical_pathname (source) +@ + @(return translate_logical_pathname(source)) +@) + +void +init_pathname(void) +{ + SYM_VAL(Vdefault_pathname_defaults) = + make_pathname(Cnil, Cnil, Cnil, Cnil, Cnil, Cnil); +} diff --git a/src/c/predicate.d b/src/c/predicate.d new file mode 100644 index 000000000..7c764d74e --- /dev/null +++ b/src/c/predicate.d @@ -0,0 +1,515 @@ +/* + predicate.c -- Predicates. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +@(defun identity (x) +@ + @(return x) +@) + +@(defun null (x) +@ + @(return (Null(x) ? Ct : Cnil)) +@) + +@(defun symbolp (x) +@ + @(return (SYMBOLP(x) ? Ct : Cnil)) +@) + +@(defun atom (x) +@ + @(return (ATOM(x) ? Ct : Cnil)) +@) + +@(defun consp (x) +@ + @(return (CONSP(x) ? Ct : Cnil)) +@) + +@(defun listp (x) +@ + @(return ((Null(x) || CONSP(x)) ? Ct : Cnil)) +@) + +@(defun numberp (x) + enum type t; +@ + t = type_of(x); + @(return (NUMBER_TYPE(t) ? Ct : Cnil)) +@) + +/* Used in compiled code */ +bool numberp(cl_object x) +{ + enum type t = type_of(x); + return(NUMBER_TYPE(t)); +} + +@(defun integerp (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_fixnum || t == t_bignum) ? Ct : Cnil)) +@) + +@(defun rationalp (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_fixnum || t == t_bignum || t == t_ratio) ? Ct : Cnil)) +@) + +@(defun floatp (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_longfloat || t == t_shortfloat) ? Ct : Cnil)) +@) + +@(defun realp (x) + enum type t; +@ + t = type_of(x); + @(return (REAL_TYPE(t) ? Ct : Cnil)) +@) + +@(defun complexp (x) +@ + @(return ((type_of(x) == t_complex) ? Ct : Cnil)) +@) + +@(defun characterp (x) +@ + @(return (CHARACTERP(x) ? Ct : Cnil)) +@) + +@(defun stringp (x) +@ + @(return ((type_of(x) == t_string) ? Ct : Cnil)) +@) + +@(defun bit_vector_p (x) +@ + @(return ((type_of(x) == t_bitvector) ? Ct : Cnil)) +@) + +@(defun vectorp (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_vector || t == t_string || t == t_bitvector) ? Ct : Cnil)) +@) + +@(defun simple_string_p (x) +@ + @(return ((type_of(x) == t_string && + !x->string.adjustable && + !x->string.hasfillp && + Null(CAR(x->string.displaced))) ? Ct : Cnil)) +@) + +@(defun simple_bit_vector_p (x) +@ + @(return ((type_of(x) == t_bitvector && + !x->vector.adjustable && + !x->vector.hasfillp && + Null(CAR(x->vector.displaced))) ? Ct : Cnil)) +@) + +@(defun simple_vector_p (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_vector && + !x->vector.adjustable && + !x->vector.hasfillp && + Null(CAR(x->vector.displaced)) && + (enum aelttype)x->vector.elttype == aet_object) ? Ct : Cnil)) +@) + +@(defun arrayp (x) + enum type t; +@ + t = type_of(x); + @(return (ARRAY_TYPE(t) ? Ct : Cnil)) +@) + +@(defun packagep (x) +@ + @(return ((type_of(x) == t_package) ? Ct : Cnil)) +@) + +@(defun functionp (x) + enum type t; + cl_object output; +@ + t = type_of(x); + if (t == t_bytecodes || t == t_cfun || t == t_cclosure) + output = Ct; + else + output = Cnil; + @(return output) +@) + +@(defun compiled_function_p (x) + enum type t; +@ + t = type_of(x); + @(return ((t == t_bytecodes || t == t_cfun || t == t_cclosure) ? Ct : Cnil)) +@) + +@(defun commonp (x) + cl_object output; +@ + output = (FALSE /* type_of(x) == t_spice */ +#ifdef THREADS + || type_of(x) == t_thread + || type_of(x) == t_cont +#endif THREADS +#ifdef CLOS + || type_of(x) == t_instance + || type_of(x) == t_gfun +#endif CLOS + ) ? Cnil : Ct; + @(return output) +@) + +@(defun eq (x y) +@ + @(return ((x == y) ? Ct : Cnil)) +@) + +bool +eql(cl_object x, cl_object y) +{ + enum type t; + + if (x == y) + return(TRUE); + if ((t = type_of(x)) != type_of(y)) + return(FALSE); + switch (t) { + + case t_fixnum: + return(fix(x) == fix(y)); + + case t_bignum: + return(big_compare(x, y) == 0); + + case t_ratio: + return(eql(x->ratio.num, y->ratio.num) && + eql(x->ratio.den, y->ratio.den)); + + case t_shortfloat: + return(sf(x) == sf(y)); + + case t_longfloat: + return(lf(x) == lf(y)); + + case t_complex: + if (eql(x->complex.real, y->complex.real) && + eql(x->complex.imag, y->complex.imag)) + return(TRUE); + else + return(FALSE); + + case t_character: + return(CHAR_CODE(x) == CHAR_CODE(y)); + + default: + return(FALSE); + } +} + +@(defun eql (x y) +@ + @(return (eql(x, y) ? Ct : Cnil)) +@) + +bool +equal(register cl_object x, cl_object y) +{ + register enum type t; + + cs_check(y); +BEGIN: + if ((t = type_of(x)) != type_of(y)) + return(FALSE); + if (x==y) + return(TRUE); + switch (t) { + + case t_cons: + if (!equal(CAR(x), CAR(y))) + return(FALSE); + x = CDR(x); + y = CDR(y); + goto BEGIN; + + case t_symbol: + case t_vector: + case t_array: + return FALSE; + + case t_fixnum: + return(fix(x)==fix(y)); + + case t_shortfloat: + return(x->SF.SFVAL==y->SF.SFVAL); + + case t_longfloat: + return(x->LF.LFVAL==y->LF.LFVAL); + + case t_string: + return(string_eq(x, y)); + + case t_bitvector: { + cl_index i, ox, oy; + + if (x->vector.fillp != y->vector.fillp) + return(FALSE); + ox = x->vector.offset; + oy = y->vector.offset; + for (i = 0; i < x->vector.fillp; i++) + if((x->vector.self.bit[(i+ox)/8] & (0200>>(i+ox)%8)) + !=(y->vector.self.bit[(i+oy)/8] & (0200>>(i+oy)%8))) + return(FALSE); + return(TRUE); + } + +#ifdef CLOS + case t_instance: { + cl_index i; + + if (x->instance.class != y->instance.class) + return(FALSE); + for (i = 0; i < x->instance.length; i++) + if (!equal(x->instance.slots[i], y->instance.slots[i])) + return(FALSE); + return(TRUE); + } +#else + case t_structure: + { + int i; + + if (x->str.name != y->str.name) + return(FALSE); + for (i = 0; i < x->str.length; i++) + if (!equal(x->str.self[i], y->str.self[i])) + return(FALSE); + return(TRUE); + } +#endif CLOS + + case t_pathname: + return(equal(x->pathname.host, y->pathname.host) && + equal(x->pathname.device, y->pathname.device) && + equal(x->pathname.directory, y->pathname.directory) && + equal(x->pathname.name, y->pathname.name) && + equal(x->pathname.type, y->pathname.type) && + equal(x->pathname.version, y->pathname.version)); + + default: + return(eql(x,y)); + } +} + +@(defun equal (x y) +@ + @(return (equal(x, y) ? Ct : Cnil)) +@) + +bool +equalp(cl_object x, cl_object y) +{ + enum type tx, ty; + cl_index j; + + cs_check(x); + +BEGIN: + if (eql(x, y)) + return(TRUE); + tx = type_of(x); + ty = type_of(y); + + switch (tx) { + case t_fixnum: + case t_bignum: + case t_ratio: + case t_shortfloat: + case t_longfloat: + case t_complex: + if (ty == t_fixnum || ty == t_bignum || ty == t_ratio || + ty == t_shortfloat || ty == t_longfloat || + ty == t_complex) + return number_equalp(x, y); + else + return FALSE; + + case t_vector: + case t_string: + case t_bitvector: + if (ty == t_vector || ty == t_string || ty == t_bitvector) { + j = x->vector.fillp; + if (j != y->vector.fillp) + return FALSE; + goto ARRAY; + } + else + return(FALSE); + + case t_array: + if (ty == t_array && x->array.rank == y->array.rank) { + if (x->array.rank > 1) { + cl_index i = 0; + for (i = 0; i < x->array.rank; i++) + if (x->array.dims[i] != y->array.dims[i]) return(FALSE); + } + if (x->array.dim != y->array.dim) + return(FALSE); + j=x->array.dim; + goto ARRAY; + } + else + return(FALSE); + + default: + } + if (tx != ty) + return(FALSE); + switch (tx) { + case t_character: + return(char_equal(x, y)); + + case t_cons: + if (!equalp(CAR(x), CAR(y))) + return(FALSE); + x = CDR(x); + y = CDR(y); + goto BEGIN; + +#ifdef CLOS + case t_instance: { + cl_index i; + + if (x->instance.class != y->instance.class) + return(FALSE); + for (i = 0; i < x->instance.length; i++) + if (!equal(x->instance.slots[i], y->instance.slots[i])) + return(FALSE); + return(TRUE); + } +#else + case t_structure: { + cl_index i; + + if (x->str.name != y->str.name) + return(FALSE); + for (i = 0; i < x->str.length; i++) + if (!equalp(x->str.self[i], y->str.self[i])) + return(FALSE); + return(TRUE); + } +#endif CLOS + + case t_pathname: + return(equal(x, y)); + + default: + return(FALSE); + } + +ARRAY: + { + cl_index i; + + for (i = 0; i < j; i++) + if (!equalp(aref(x, i), aref(y, i))) + return(FALSE); + return(TRUE); + } +} + +@(defun equalp (x y) +@ + @(return (equalp(x, y) ? Ct : Cnil)) +@) + +/* + Contains_sharp_comma returns TRUE, iff the argument contains + a cons whose car is si:|#,| or a STRUCTURE. + Refer to the compiler about this magic. +*/ +bool +contains_sharp_comma(cl_object x) +{ + enum type tx; + + cs_check(x); + +BEGIN: + tx = type_of(x); + if (tx == t_complex) + return(contains_sharp_comma(x->complex.real) || + contains_sharp_comma(x->complex.imag)); + if (tx == t_vector) { + cl_index i; + for (i = 0; i < x->vector.fillp; i++) + if (contains_sharp_comma(x->vector.self.t[i])) + return(TRUE); + return(FALSE); + } + if (tx == t_cons) { + if (CAR(x) == siSsharp_comma) + return(TRUE); + if (contains_sharp_comma(CAR(x))) + return(TRUE); + x = CDR(x); + goto BEGIN; + } + if (tx == t_array) { + cl_index i, j; + for (i = 0, j = 1; i < x->array.rank; i++) + j *= x->array.dims[i]; + for (i = 0; i < j; i++) + if (contains_sharp_comma(x->array.self.t[i])) + return(TRUE); + return(FALSE); + } +#ifdef CLOS + if (tx == t_instance) + return(TRUE); /* Oh, my god! */ +#else + if (tx == t_structure) + return(TRUE); /* Oh, my god! */ +#endif CLOS + return(FALSE); +} + +@(defun si::contains_sharp_comma (x) +@ + @(return (contains_sharp_comma(x) ? Ct : Cnil)) +@) + +@(defun si::fixnump (x) +@ + @(return (FIXNUMP(x) ? Ct : Cnil)) +@) diff --git a/src/c/print.d b/src/c/print.d new file mode 100644 index 000000000..73c2ab792 --- /dev/null +++ b/src/c/print.d @@ -0,0 +1,2337 @@ +/* + print.d -- Print. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include +#include + +extern void *alloca(size_t size); + +/******************************* EXPORTS ******************************/ + +cl_object Kupcase; +cl_object Kdowncase; +cl_object Kcapitalize; + +cl_object Kstream; +cl_object Kescape; +cl_object Kpretty; +cl_object Kcircle; +cl_object Kbase; +cl_object Kradix; +cl_object Kcase; +cl_object Kgensym; +cl_object Klevel; +cl_object Klength; +cl_object Karray; + +cl_object Vprint_escape; +cl_object Vprint_pretty; +cl_object Vprint_circle; +cl_object Vprint_base; +cl_object Vprint_radix; +cl_object Vprint_case; +cl_object Vprint_gensym; +cl_object Vprint_level; +cl_object Vprint_length; +cl_object Vprint_array; + +cl_object siVprint_package; +cl_object siVprint_structure; + +#ifndef THREADS +bool PRINTescape; +bool PRINTpretty; +bool PRINTcircle; +int PRINTbase; +bool PRINTradix; +cl_object PRINTcase; +bool PRINTgensym; +int PRINTlevel; +int PRINTlength; +bool PRINTarray; +void (*write_ch_fun)(); /* virtual output (for pretty-print) */ +void (*output_ch_fun)(); /* physical output */ +#endif THREADS + +/******************************* ------- ******************************/ + +#define LINE_LENGTH 72 + +#define to_be_escaped(c) \ + (standard_readtable->readtable.table[(c)&0377].syntax_type \ + != cat_constituent || \ + islower((c)&0377) || (c) == ':') + + +cl_object PRINTpackage; +bool PRINTstructure; + +#ifdef CLOS +cl_object Sstream_write_char, + Sstream_write_string, + Sstream_fresh_line, + Sstream_clear_output, + Sstream_force_output; +#endif CLOS + +#define write_ch (*write_ch_fun) +#define output_ch (*output_ch_fun) + +cl_object siSpretty_print_format; +cl_object siSsharp_exclamation; + +#define MARK 0400 +#define UNMARK 0401 +#define SET_INDENT 0402 +#define INDENT 0403 +#define INDENT1 0404 +#define INDENT2 0405 + +#define mod(x) ((x)%Q_SIZE) + +#ifdef THREADS + +#define queue clwp->lwp_queue +#define indent_stack clwp->lwp_indent_stack +#define qh clwp->lwp_qh +#define qt clwp->lwp_qt +#define qc clwp->lwp_qc +#define isp clwp->lwp_isp +#define iisp clwp->lwp_iisp + +#define CIRCLEjmp clwp->lwp_CIRCLEjmp +#define CIRCLEbase clwp->lwp_CIRCLEbase +#define CIRCLEtop clwp->lwp_CIRCLEtop +#define CIRCLElimit clwp->lwp_CIRCLElimit + +#else +static short queue[Q_SIZE]; +static short indent_stack[IS_SIZE]; + +static int qh; +static int qt; +static int qc; +static int isp; +static int iisp; + +jmp_buf CIRCLEjmp; +cl_object *CIRCLEbase; +cl_object *CIRCLEtop; +cl_object *CIRCLElimit; +cl_object PRINTstream; + +#endif THREADS + +#ifdef CLOS + +static void flush_queue (bool force); +static void write_decimal1 (int i); +static void travel_push_object (cl_object x); + +void +interactive_writec_stream(int c, cl_object stream) +{ + funcall(3, Sstream_write_char, stream, code_char(c)); +} + +void +flush_interactive_stream(cl_object stream) +{ + funcall(2, Sstream_force_output, stream); +} + +#define FLUSH_STREAM(strm) \ + if (type_of(strm) == t_stream) flush_stream(strm); \ + else flush_interactive_stream(strm) +#define FILE_COLUMN(strm) \ + ((type_of(strm) == t_instance) ? -1 : file_column(strm)) +#else +#define FLUSH_STREAM(strm) flush_stream(strm) +#define FILE_COLUMN(strm) file_column(strm) +#endif CLOS + +static void +writec_queue(int c) +{ + if (qc >= Q_SIZE) + flush_queue(FALSE); + if (qc >= Q_SIZE) + FEerror("Can't pretty-print.", 0); + queue[qt] = c; + qt = mod(qt+1); + qc++; +} + +static void +flush_queue(bool force) +{ + int c, i, j, k, l, i0; + +BEGIN: + while (qc > 0) { + c = queue[qh]; + if (c == MARK) + goto DO_MARK; + else if (c == UNMARK) + isp -= 2; + else if (c == SET_INDENT) + indent_stack[isp] = FILE_COLUMN(PRINTstream); + else if (c == INDENT) { + goto DO_INDENT; + } else if (c == INDENT1) { + i = FILE_COLUMN(PRINTstream)-indent_stack[isp]; + if (i < 8 && indent_stack[isp] < LINE_LENGTH/2) { + output_ch(' '); + indent_stack[isp] + = FILE_COLUMN(PRINTstream); + } else { + if (indent_stack[isp] < LINE_LENGTH/2) { + indent_stack[isp] + = indent_stack[isp-1] + 4; + } + goto DO_INDENT; + } + } else if (c == INDENT2) { + indent_stack[isp] = indent_stack[isp-1] + 2; + goto PUT_INDENT; + } else if (c < 0400) + output_ch(c); + qh = mod(qh+1); + --qc; + } + return; + +DO_MARK: + k = LINE_LENGTH - 1 - FILE_COLUMN(PRINTstream); + for (i = 1, j = 0, l = 1; l > 0 && i < qc && j < k; i++) { + c = queue[mod(qh + i)]; + if (c == MARK) + l++; + else if (c == UNMARK) + --l; + else if (c == INDENT || c == INDENT1 || c == INDENT2) + j++; + else if (c < 0400) + j++; + } + if (l == 0) + goto FLUSH; + if (i == qc && !force) + return; + qh = mod(qh+1); + --qc; + if (++isp >= IS_SIZE-1) + FEerror("Can't pretty-print.", 0); + indent_stack[isp++] = FILE_COLUMN(PRINTstream); + indent_stack[isp] = indent_stack[isp-1]; + goto BEGIN; + +DO_INDENT: + if (iisp > isp) + goto PUT_INDENT; + k = LINE_LENGTH - 1 - FILE_COLUMN(PRINTstream); + for (i0 = 0, i = 1, j = 0, l = 1; i < qc && j < k; i++) { + c = queue[mod(qh + i)]; + if (c == MARK) + l++; + else if (c == UNMARK) { + if (--l == 0) + goto FLUSH; + } else if (c == SET_INDENT) { + if (l == 1) + break; + } else if (c == INDENT) { + if (l == 1) + i0 = i; + j++; + } else if (c == INDENT1) { + if (l == 1) + break; + j++; + } else if (c == INDENT2) { + if (l == 1) { + i0 = i; + break; + } + j++; + } else if (c < 0400) + j++; + } + if (i == qc && !force) + return; + if (i0 == 0) + goto PUT_INDENT; + i = i0; + goto FLUSH; + +PUT_INDENT: + qh = mod(qh+1); + --qc; + output_ch('\n'); + for (i = indent_stack[isp]; i > 0; --i) + output_ch(' '); + iisp = isp; + goto BEGIN; + +FLUSH: + for (j = 0; j < i; j++) { + c = queue[qh]; + if (c == INDENT || c == INDENT1 || c == INDENT2) + output_ch(' '); + else if (c < 0400) + output_ch(c); + qh = mod(qh+1); + --qc; + } + goto BEGIN; +} + +void +writec_PRINTstream(int c) +{ + if (c == INDENT || c == INDENT1) + writec_stream(' ', PRINTstream); + else if (c < 0400) + writec_stream(c, PRINTstream); +} + +#ifdef CLOS +static void +interactive_writec_PRINTstream(int c) +{ + if (c == INDENT || c == INDENT1) + interactive_writec_stream(' ', PRINTstream); + else if (c < 0400) + interactive_writec_stream(c, PRINTstream); +} +#endif CLOS + +void +write_str(char *s) +{ + while (*s != '\0') + write_ch(*s++); +} + +void +write_decimal(int i) +{ + if (i == 0) { + write_ch('0'); + return; + } + write_decimal1(i); +} + +static void +write_decimal1(int i) +{ + if (i == 0) + return; + write_decimal1(i/10); + write_ch(i%10 + '0'); +} + +void +write_addr(cl_object x) +{ + cl_fixnum i, j; + + i = (cl_index)x; + for (j = sizeof(i)-4; j >= 0; j -= 4) { + int k = (i>>j) & 0xf; + if (k < 10) + write_ch('0' + k); + else + write_ch('a' + k - 10); + } +} + +static void +write_base(void) +{ + if (PRINTbase == 2) + write_str("#b"); + else if (PRINTbase == 8) + write_str("#o"); + else if (PRINTbase == 16) + write_str("#x"); + else if (PRINTbase >= 10) { + write_ch('#'); + write_ch(PRINTbase/10+'0'); + write_ch(PRINTbase%10+'0'); + write_ch('r'); + } else { + write_ch('#'); + write_ch(PRINTbase+'0'); + write_ch('r'); + } +} + +/* The floating point precision is required to make the + most-positive-long-float printed expression readable. + If this is too small, then the rounded off fraction, may be too big + to read */ + +#ifndef FPRC +#define FPRC 16 +#endif + +void +edit_double(int n, double d, int *sp, char *s, int *ep) +{ + char *p, buff[FPRC + 9]; + int i; + +#ifdef IEEEFLOAT + if ((*((int *)&d +HIND) & 0x7ff00000) == 0x7ff00000) + FEerror("Can't print a non-number.", 0); + else + sprintf(buff, "%*.*e",FPRC+8,FPRC, d); + if (buff[FPRC+3] != 'e') { + sprintf(buff, "%*.*e",FPRC+7,FPRC,d); + *ep = (buff[FPRC+5]-'0')*10 + (buff[FPRC+6]-'0'); + } else + *ep = (buff[FPRC+5]-'0')*100 + + (buff[FPRC+6]-'0')*10 + (buff[FPRC+7]-'0'); + *sp = 1; + if (buff[0] == '-') + *sp *= -1; +#else + sprintf(buff, "%*.*e",FPRC+7,FPRC, d); + /* "-D.MMMMMMMMMMMMMMMe+EE" */ + /* 0123456789012345678901 */ + *sp = 1; + if (buff[0] == '-') + *sp *= -1; + *ep = (buff[FPRC+5]-'0')*10 + (buff[FPRC+6]-'0'); +#endif IEEEFLOAT + + if (buff[FPRC+4] == '-') + *ep *= -1; + buff[2] = buff[1]; + p = buff + 2; + if (n < FPRC+1) { + if (p[n] >= '5') { + for (i = n - 1; i >= 0; --i) + if (p[i] == '9') + p[i] = '0'; + else { + p[i]++; + break; + } + if (i < 0) { + *--p = '1'; + (*ep)++; + } + } + for (i = 0; i < n; i++) + s[i] = p[i]; + } else { + for (i = 0; i < FPRC+1; i++) + s[i] = p[i]; + for (; i < n; i++) + s[i] = '0'; + } + s[n] = '\0'; +} + + +void +write_double(double d, int e, bool shortp) +{ + int sign; + char buff[FPRC+5]; + int exp; + int i; + int n = FPRC; /* was FPRC+1 */ + + if (shortp) + n = 7; + edit_double(n, d, &sign, buff, &exp); + if (sign==2) { + write_str("#<"); + write_str(buff); + write_ch('>'); + return; + } + if (sign < 0) + write_ch('-'); + if (-3 <= exp && exp < 7) { + if (exp < 0) { + write_ch('0'); + write_ch('.'); + exp = (-exp) - 1; + for (i = 0; i < exp; i++) + write_ch('0'); + for (; n > 0; --n) + if (buff[n-1] != '0') + break; + if (exp == 0 && n == 0) + n = 1; + for (i = 0; i < n; i++) + write_ch(buff[i]); + } else { + exp++; + for (i = 0; i < exp; i++) + if (i < n) + write_ch(buff[i]); + else + write_ch('0'); + write_ch('.'); + if (i < n) + write_ch(buff[i]); + else + write_ch('0'); + i++; + for (; n > i; --n) + if (buff[n-1] != '0') + break; + for (; i < n; i++) + write_ch(buff[i]); + } + exp = 0; + } else { + write_ch(buff[0]); + write_ch('.'); + write_ch(buff[1]); + for (; n > 2; --n) + if (buff[n-1] != '0') + break; + for (i = 2; i < n; i++) + write_ch(buff[i]); + } + if (exp == 0 && e == 0) + return; + if (e == 0) + e = 'E'; + write_ch(e); + if (exp < 0) { + write_ch('-'); + exp *= -1; + } + write_decimal(exp); +} + + +#ifndef CLOS +static void +call_structure_print_function(cl_object x, int level) +{ + int i; + bool eflag; + bds_ptr old_bds_top; + + void (*wf)() = write_ch_fun; + + bool e = PRINTescape; + bool r = PRINTradix; + int b = PRINTbase; + bool c = PRINTcircle; + bool p = PRINTpretty; + int lv = PRINTlevel; + int ln = PRINTlength; + bool g = PRINTgensym; + bool a = PRINTarray; + cl_object ps = PRINTstream; + cl_object pc = PRINTcase; + + short ois[IS_SIZE]; + + int oqh; + int oqt; + int oqc; + int oisp; + int oiisp; + + while (interrupt_flag) { + interrupt_flag = FALSE; +#ifdef unix + alarm(0); +#endif unix + terminal_interrupt(TRUE); + } + + if (PRINTpretty) + flush_queue(TRUE); + + oqh = qh; + oqt = qt; + oqc = qc; + oisp = isp; + oiisp = iisp; + + for (i = 0; i <= isp; i++) + ois[i] = indent_stack[i]; + + old_bds_top = bds_top; + bds_bind(Vprint_escape, PRINTescape?Ct:Cnil); + bds_bind(Vprint_radix, PRINTradix?Ct:Cnil); + bds_bind(Vprint_base, MAKE_FIXNUM(PRINTbase)); + bds_bind(Vprint_circle, PRINTcircle?Ct:Cnil); + bds_bind(Vprint_pretty, PRINTpretty?Ct:Cnil); + bds_bind(Vprint_level, PRINTlevel<0?Cnil:MAKE_FIXNUM(PRINTlevel)); + bds_bind(Vprint_length, PRINTlength<0?Cnil:MAKE_FIXNUM(PRINTlength)); + bds_bind(Vprint_gensym, PRINTgensym?Ct:Cnil); + bds_bind(Vprint_array, PRINTarray?Ct:Cnil); + bds_bind(Vprint_case, PRINTcase); + + if (frs_push(FRS_PROTECT, Cnil)) + eflag = TRUE; + else { + funcall(4, getf(x->str.name->symbol.plist, + siSstructure_print_function, Cnil), + x, PRINTstream, MAKE_FIXNUM(level)); + eflag = FALSE; + } + + frs_pop(); + bds_unwind(old_bds_top); + + for (i = 0; i <= oisp; i++) + indent_stack[i] = ois[i]; + + iisp = oiisp; + isp = oisp; + qc = oqc; + qt = oqt; + qh = oqh; + + PRINTcase = pc; + PRINTstream = ps; + PRINTarray = a; + PRINTgensym = g; + PRINTlength = ln; + PRINTlevel = lv; + PRINTpretty = p; + PRINTcircle = c; + PRINTbase = b; + PRINTradix = r; + PRINTescape = e; + + write_ch_fun = wf; + + if (eflag) unwind(nlj_fr, nlj_tag); +} + +#else +static void +call_print_object(cl_object x, int level) +{ + int i; + bool eflag; + bds_ptr old_bds_top; + + void (*wf)() = write_ch_fun; + + bool e = PRINTescape; + bool r = PRINTradix; + int b = PRINTbase; + bool c = PRINTcircle; + bool p = PRINTpretty; + int lv = PRINTlevel; + int ln = PRINTlength; + bool g = PRINTgensym; + bool a = PRINTarray; + cl_object ps = PRINTstream; + cl_object pc = PRINTcase; + + short ois[IS_SIZE]; + + int oqh; + int oqt; + int oqc; + int oisp; + int oiisp; + + while (interrupt_flag) { + interrupt_flag = FALSE; +#ifdef unix + alarm(0); +#endif + terminal_interrupt(TRUE); + } + + if (PRINTpretty) + flush_queue(TRUE); + + oqh = qh; + oqt = qt; + oqc = qc; + oisp = isp; + oiisp = iisp; + + for (i = 0; i <= isp; i++) + ois[i] = indent_stack[i]; + + old_bds_top = bds_top; + bds_bind(Vprint_escape, PRINTescape?Ct:Cnil); + bds_bind(Vprint_radix, PRINTradix?Ct:Cnil); + bds_bind(Vprint_base, MAKE_FIXNUM(PRINTbase)); + bds_bind(Vprint_circle, PRINTcircle?Ct:Cnil); + bds_bind(Vprint_pretty, PRINTpretty?Ct:Cnil); + bds_bind(Vprint_level, PRINTlevel<0?Cnil:MAKE_FIXNUM(PRINTlevel)); + bds_bind(Vprint_length, PRINTlength<0?Cnil:MAKE_FIXNUM(PRINTlength)); + bds_bind(Vprint_gensym, PRINTgensym?Ct:Cnil); + bds_bind(Vprint_array, PRINTarray?Ct:Cnil); + bds_bind(Vprint_case, PRINTcase); + + + if (frs_push(FRS_PROTECT, Cnil)) + eflag = TRUE; + else { + funcall(3, Sprint_object, x, PRINTstream); + eflag = FALSE; + } + + frs_pop(); + bds_unwind(old_bds_top); + + for (i = 0; i <= oisp; i++) + indent_stack[i] = ois[i]; + + iisp = oiisp; + isp = oisp; + qc = oqc; + qt = oqt; + qh = oqh; + + PRINTcase = pc; + PRINTstream = ps; + PRINTarray = a; + PRINTgensym = g; + PRINTlength = ln; + PRINTlevel = lv; + PRINTpretty = p; + PRINTcircle = c; + PRINTbase = b; + PRINTradix = r; + PRINTescape = e; + + write_ch_fun = wf; + + if (eflag) unwind(nlj_fr, nlj_tag); +} +#endif CLOS + +void +write_fixnum(cl_fixnum i) +{ + short digits[16]; + int j; + for (j = 0; j < 16 && i != 0; i /= PRINTbase) + digits[j++] = digit_weight(i%PRINTbase, PRINTbase); + if (j == 16) write_fixnum(i); + while (j-- > 0) + write_ch(digits[j]); +} + +void +write_bignum(cl_object x) +{ + cl_fixnum str_size = mpz_sizeinbase(x->big.big_num, PRINTbase); + char str[str_size]; /* __GNUC__ */ + char *s = str; + mpz_get_str(str, PRINTbase, x->big.big_num); + while (*s) + write_ch(*s++); +} + +static void +write_symbol(register cl_object x) +{ + bool escaped; + cl_index i; + cl_object s = x->symbol.name; + + if (!PRINTescape) { + for (i = 0; i < s->string.fillp; i++) { + int c = s->string.self[i]; + if (isupper(c) && + (PRINTcase == Kdowncase || + (PRINTcase == Kcapitalize && i != 0))) + c = tolower(c); + write_ch(c); + } + return; + } + if (Null(x->symbol.hpack)) { + if (PRINTcircle) { + cl_object *vp; + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + write_ch('#'); + write_decimal((vp-CIRCLEbase)/2); + if (vp[1] != Cnil) { + write_ch('#'); + return; + } else { + write_ch('='); + vp[1] = Ct; + } + } + } + if (PRINTgensym) + write_str("#:"); + } else if (x->symbol.hpack == keyword_package) + write_ch(':'); + else if ((PRINTpackage != OBJNULL && x->symbol.hpack != PRINTpackage) + || find_symbol(x, current_package())!=x + || intern_flag == 0) { + escaped = 0; + for (i = 0; + i < x->symbol.hpack->pack.name->string.fillp; + i++) { + int c = x->symbol.hpack->pack.name->string.self[i]; + if (to_be_escaped(c)) + escaped = 1; + } + if (escaped) + write_ch('|'); + for (i = 0; + i < x->symbol.hpack->pack.name->string.fillp; + i++) { + int c = x->symbol.hpack->pack.name->string.self[i]; + if (c == '|' || c == '\\') + write_ch('\\'); + if (escaped == 0 && isupper(c) && + (PRINTcase == Kdowncase || + (PRINTcase == Kcapitalize && i!=0))) + c = tolower(c); + write_ch(c); + } + if (escaped) + write_ch('|'); + if (find_symbol(x, x->symbol.hpack) != x) + error("can't print symbol"); + if ((PRINTpackage != OBJNULL && + x->symbol.hpack != PRINTpackage) + || intern_flag == INTERNAL) + write_str("::"); + else if (intern_flag == EXTERNAL) + write_ch(':'); + else + FEerror("Pathological symbol --- cannot print.", 0); + } + escaped = 0; + if (potential_number_p(s, PRINTbase)) + escaped = 1; + for (i = 0; i < s->string.fillp; i++) { + int c = s->string.self[i]; + if (to_be_escaped(c)) + escaped = 1; + } + for (i = 0; i < s->string.fillp; i++) + if (s->string.self[i] != '.') + goto NOT_DOT; + escaped = 1; + + NOT_DOT: + if (escaped) + write_ch('|'); + for (i = 0; i < s->string.fillp; i++) { + int c = s->string.self[i]; + if (c == '|' || c == '\\') + write_ch('\\'); + if (escaped == 0 && isupper(c) && + (PRINTcase == Kdowncase || + (PRINTcase == Kcapitalize && i != 0))) + c = tolower(c); + write_ch(c); + } + if (escaped) + write_ch('|'); +} + +static void +write_character(register int i) +{ + if (!PRINTescape) { + write_ch(i); + return; + } + write_str("#\\"); + switch (i) { + case '\r': write_str("Return"); break; + case ' ': write_str("Space"); break; + case '\177': write_str("Rubout"); break; + case '\f': write_str("Page"); break; + case '\t': write_str("Tab"); break; + case '\b': write_str("Backspace"); break; + case '\n': write_str("Newline"); break; + case '\0': write_str("Null"); break; + default: + if (i & 0200) { + write_ch('\\'); + write_ch(((i>>6)&7) + '0'); + write_ch(((i>>3)&7) + '0'); + write_ch(((i>>0)&7) + '0'); + } else if (i < 040) { + write_ch('^'); + i += 0100; + if (i == '\\') + write_ch('\\'); + write_ch(i); + } else + write_ch(i); + break; + } +} + + +void +write_object(cl_object x, int level) +{ + cl_object r, y; + cl_fixnum i, j; + cl_index ndx, k; + cl_object *vp; + + cs_check(x); + + BEGIN: + if (x == OBJNULL) { + write_str("#"); + return; + } + + switch (type_of(x)) { + + case FREE: + write_str("#'); + return; + + case t_fixnum: + if (PRINTradix && PRINTbase != 10) + write_base(); + if (x == MAKE_FIXNUM(0)) { + write_ch('0'); + } else if (FIXNUM_MINUSP(x)) { + write_ch('-'); + write_fixnum(-fix(x)); + } else + write_fixnum(fix(x)); + if (PRINTradix && PRINTbase == 10) + write_ch('.'); + return; + + case t_bignum: + if (PRINTradix && PRINTbase != 10) + write_base(); + write_bignum(x); + if (PRINTradix && PRINTbase == 10) + write_ch('.'); + return; + + case t_ratio: + if (PRINTradix) { + write_base(); + PRINTradix = FALSE; + write_object(x->ratio.num, level); + write_ch('/'); + write_object(x->ratio.den, level); + PRINTradix = TRUE; + } else { + write_object(x->ratio.num, level); + write_ch('/'); + write_object(x->ratio.den, level); + } + return; + + case t_shortfloat: + r = symbol_value(Vread_default_float_format); + if (r == Ssingle_float || r == Sshort_float) + write_double((double)sf(x), 0, TRUE); + else + write_double((double)sf(x), 'f', TRUE); + return; + + case t_longfloat: + r = symbol_value(Vread_default_float_format); + if (r == Slong_float || r == Sdouble_float) + write_double(lf(x), 0, FALSE); + else + write_double(lf(x), 'd', FALSE); + return; + + case t_complex: + write_str("#C("); + write_object(x->complex.real, level); + write_ch(' '); + write_object(x->complex.imag, level); + write_ch(')'); + return; + + case t_character: + write_character(CHAR_CODE(x)); + return; + + case t_symbol: + write_symbol(x); + return; + + case t_array: { + int subscripts[ARANKLIM]; + cl_index n, m, k, i; + + if (!PRINTarray) { + write_str("#'); + return; + } + if (PRINTcircle) { + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + write_ch('#'); + write_decimal((vp-CIRCLEbase)/2); + if (vp[1] != Cnil) { + write_ch('#'); + return; + } else { + write_ch('='); + vp[1] = Ct; + break; + } + } + } + if (PRINTlevel >= 0 && level >= PRINTlevel) { + write_ch('#'); + return; + } + n = x->array.rank; + write_ch('#'); + write_decimal(n); + write_ch('A'); + if (PRINTlevel >= 0 && level+n >= PRINTlevel) + n = PRINTlevel - level; + for (j = 0; j < n; j++) + subscripts[j] = 0; + for (m = 0, j = 0;;) { + for (i = j; i < n; i++) { + if (subscripts[i] == 0) { + write_ch(MARK); + write_ch('('); + write_ch(SET_INDENT); + if (x->array.dims[i] == 0) { + write_ch(')'); + write_ch(UNMARK); + j = i-1; + k = 0; + goto INC; + } + } + if (subscripts[i] > 0) + write_ch(INDENT); + if (PRINTlength >= 0 && + subscripts[i] >= PRINTlength) { + write_str("...)"); + write_ch(UNMARK); + k=x->array.dims[i]-subscripts[i]; + subscripts[i] = 0; + for (j = i+1; j < n; j++) + k *= x->array.dims[j]; + j = i-1; + goto INC; + } + } + /* FIXME: This conses! */ + if (n == x->array.rank) + write_object(aref(x, m), level+n); + else + write_ch('#'); + j = n-1; + k = 1; + + INC: + while (j >= 0) { + if (++subscripts[j] < x->array.dims[j]) + break; + subscripts[j] = 0; + write_ch(')'); + write_ch(UNMARK); + --j; + } + if (j < 0) + break; + m += k; + } + return; + } + + case t_vector: + if (!PRINTarray) { + write_str("#vector.dim); + write_ch(' '); + write_addr(x); + write_ch('>'); + return; + } + if (PRINTcircle) { + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + write_ch('#'); + write_decimal((vp-CIRCLEbase)/2); + if (vp[1] != Cnil) { + write_ch('#'); + return; + } else { + write_ch('='); + vp[1] = Ct; + break; + } + } + } + if (PRINTlevel >= 0 && level >= PRINTlevel) { + write_ch('#'); + return; + } + write_ch('#'); + write_ch(MARK); + write_ch('('); + write_ch(SET_INDENT); + if (x->vector.fillp > 0) { + if (PRINTlength == 0) { + write_str("...)"); + write_ch(UNMARK); + return; + } + write_object(aref(x, 0), level+1); + for (ndx = 1; ndx < x->vector.fillp; ndx++) { + write_ch(INDENT); + if (PRINTlength>=0 && ndx>=PRINTlength){ + write_str("..."); + break; + } + write_object(aref(x, ndx), level+1); + } + } + write_ch(')'); + write_ch(UNMARK); + return; + + case t_string: + if (!PRINTescape) { + for (ndx = 0; ndx < x->string.fillp; ndx++) + write_ch(x->string.self[ndx]); + return; + } + write_ch('"'); + for (ndx = 0; ndx < x->string.fillp; ndx++) { + int c = x->string.self[ndx]; + if (c == '"' || c == '\\') + write_ch('\\'); + write_ch(c); + } + write_ch('"'); + break; + + case t_bitvector: + if (!PRINTarray) { + write_str("#'); + break; + } + write_str("#*"); + for (ndx = 0; ndx < x->vector.fillp; ndx++) + if (x->vector.self.bit[ndx/8] & (0200 >> ndx%8)) + write_ch('1'); + else + write_ch('0'); + break; + + case t_cons: + if (CAR(x) == siSsharp_comma) { + write_str("#."); + x = CDR(x); + goto BEGIN; + } + if (CAR(x) == siSsharp_exclamation) { + write_str("#!"); + x = CDR(x); + goto BEGIN; + } + if (PRINTcircle) { + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + write_ch('#'); + write_decimal((vp-CIRCLEbase)/2); + if (vp[1] != Cnil) { + write_ch('#'); + return; + } else { + write_ch('='); + vp[1] = Ct; + break; + } + } + } + if (CAR(x) == Squote && CONSP(CDR(x)) && Null(CDDR(x))) { + write_ch('\''); + x = CADR(x); + goto BEGIN; + } + if (CAR(x) == Sfunction && CONSP(CDR(x)) && Null(CDDR(x))) { + write_ch('#'); + write_ch('\''); + x = CADR(x); + goto BEGIN; + } + if (PRINTlevel >= 0 && level >= PRINTlevel) { + write_ch('#'); + return; + } + write_ch(MARK); + write_ch('('); + write_ch(SET_INDENT); + if (PRINTpretty && CAR(x) != OBJNULL && + type_of(CAR(x)) == t_symbol && + (r = getf(CAR(x)->symbol.plist, + siSpretty_print_format, Cnil)) != Cnil) + goto PRETTY_PRINT_FORMAT; + for (i = 0; ; i++) { + if (PRINTlength >= 0 && i >= PRINTlength) { + write_str("..."); + break; + } + y = CAR(x); + x = CDR(x); + write_object(y, level+1); + /* FIXME! */ + if (x == OBJNULL || ATOM(x)) { + if (x != Cnil) { + write_ch(INDENT); + write_str(". "); + write_object(x, level); + } + break; + } + if (PRINTcircle) { + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + if (vp[1] != Cnil) { + write_str(" . #"); + write_decimal((vp-CIRCLEbase)/2); + write_ch('#'); + goto RIGHT_PAREN; + } else { + write_ch(INDENT); + write_str(". "); + write_object(x, level); + goto RIGHT_PAREN; + } + } + } + if (i == 0 && y != OBJNULL && type_of(y) == t_symbol) + write_ch(INDENT1); + else + write_ch(INDENT); + } + + RIGHT_PAREN: + write_ch(')'); + write_ch(UNMARK); + return; + + PRETTY_PRINT_FORMAT: + j = fixint(r); + for (i = 0; ; i++) { + if (PRINTlength >= 0 && i >= PRINTlength) { + write_str("..."); + break; + } + y = CAR(x); + x = CDR(x); + if (i <= j && Null(y)) + write_str("()"); + else + write_object(y, level+1); + /* FIXME! */ + if (x == OBJNULL || ATOM(x)) { + if (x != Cnil) { + write_ch(INDENT); + write_str(". "); + write_object(x, level); + } + break; + } + if (i >= j) + write_ch(INDENT2); + else if (i == 0) + write_ch(INDENT1); + else + write_ch(INDENT); + } + goto RIGHT_PAREN; + + case t_package: + write_str("#<"); + write_object(x->pack.name, level); + write_str(" package>"); + break; + + case t_hashtable: + write_str("#'); + break; + + case t_stream: + switch ((enum smmode)x->stream.mode) { + case smm_closed: + write_str("#stream.object1, level); + break; + + case smm_input: + write_str("#stream.object1, level); + break; + + case smm_output: + write_str("#stream.object1, level); + break; + + case smm_io: + write_str("#stream.object1, level); + break; + + case smm_probe: + write_str("#stream.object1, level); + break; + + case smm_synonym: + write_str("#stream.object0, level); + break; + + case smm_broadcast: + write_str("#stream.object0; + k = y->string.fillp; + for (ndx = 0; ndx < k && ndx < 16; ndx++) + write_ch(y->string.self[ndx]); + if (k > 16) + write_str("..."); + write_ch('"'); + break; + + case smm_string_output: + write_str("#'); + break; + + case t_random: + write_str("#$"); + write_object(MAKE_FIXNUM(x->random.value), level); + break; + +#ifndef CLOS + case t_structure: + if (PRINTcircle) { + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + write_ch('#'); + write_decimal((vp-CIRCLEbase)/2); + if (vp[1] != Cnil) { + write_ch('#'); + return; + } else { + write_ch('='); + vp[1] = Ct; + break; + } + } + } + if (PRINTlevel >= 0 && level >= PRINTlevel) { + write_ch('#'); + break; + } + if (type_of(x->str.name) != t_symbol) + FEwrong_type_argument(Ssymbol, x->str.name); + if (PRINTstructure || + Null(getf(x->str.name->symbol.plist, + siSstructure_print_function, Cnil))) { + write_str("#S"); +/* structure_to_list conses slot names and values into a list to be printed. + * print shouldn't allocate memory - Beppe + */ + x = structure_to_list(x); + write_object(x, level); + } else + call_structure_print_function(x, level); + break; +#endif CLOS + + case t_readtable: + write_str("#'); + break; + + case t_pathname: + if (PRINTescape) + write_str("#P"); + write_object(namestring(x), level); + break; + + case t_bytecodes: { + cl_object name = x->bytecodes.data[0]; + write_str("#'); + break; + } + case t_cfun: + write_str("#cfun.name != Cnil) + write_object(x->cfun.name, level); + else + write_addr(x); + write_ch('>'); + break; + case t_codeblock: + write_str("#cblock.name != Cnil) + write_object(x->cblock.name, level); + else + write_addr(x); + write_ch('>'); + break; + case t_cclosure: + write_str("#'); + break; +#ifdef LOCATIVE + case t_spice: + write_str("#<\100"); /* at-sign is the escape for dpp */ + for (i = 28; i >= 0; i -= 4) { + j = ((int)x >> i) & 0xf; + if (j < 10) + write_ch('0' + j); + else + write_ch('A' + (j - 10)); + } + write_ch('>'); + break; +#endif +#ifdef THREADS + case t_cont: + write_str("#cn.cn_thread, level); + write_ch('>'); + break; + + case t_thread: + write_str("#thread.entry, level); + write_ch(' '); + write_addr(x); + write_ch('>'); + break; +#endif THREADS +#ifdef CLOS + case t_instance: + if (type_of(x->instance.class) != t_instance) + FEwrong_type_argument(Sinstance, x->instance.class); + call_print_object(x, level); + break; + + case t_gfun: + write_str("#gfun.name != Cnil) + write_object(x->gfun.name, level); + else + write_addr(x); + write_ch('>'); + break; +#endif CLOS + +#ifdef LOCATIVE + case t_locative: + if (UNBOUNDP(x)) { + /* The next location should contain the + logical variable name */ + if (type_of(*(cl_object *)(((unsigned int)(x) >> 2) + + sizeof(cl_object))) == t_symbol) + write_object(*(cl_object *)(((unsigned int)(x) >> 2) + + sizeof(cl_object)), level); + else { + write_str("#'); + } + } + else + write_object(DEREF(x), level); + break; +#endif LOCATIVE + + default: + error("illegal type --- cannot print"); + } +} + +#define PRINTcircleSIZE 4000 + +/* To print circular structures, we traverse the structure by adding + a pair to the array CIRCLEbase for each element visited. + flag is initially NIL and becomes T if the element is visited again. + After the visit we squeeze out all the non circular elements. + The flags is used during printing to distinguish between the first visit + to the element. + */ + +/* Allocates space for travel_push: if not enough, get back with + longjmp and increase it */ + +#ifdef DOWN_STACK + +/* +fixed with new alloca() since gcc 2.7 ? +#ifdef i386 +#define SIZEincrement PRINTcircleSIZE +#endif i386 +*/ +#define SIZEincrement size + +#define setupPRINTcircle(x) \ + if (PRINTcircle) { volatile int size = PRINTcircleSIZE; \ + if (ecls_setjmp(CIRCLEjmp) != 0) \ + size += PRINTcircleSIZE; \ + CIRCLEbase = alloca(SIZEincrement * sizeof(cl_object)); \ + CIRCLElimit = &CIRCLEbase[size]; \ + setupPRINTcircle1(x); } +#else +#define setupPRINTcircle(x) \ + if (PRINTcircle) { volatile int size = PRINTcircleSIZE; \ + if (ecls_setjmp(CIRCLEjmp) != 0) { \ + size += PRINTcircleSIZE; \ + alloca(PRINTcircleSIZE * sizeof(cl_object)); \ + } else \ + CIRCLEbase = alloca(PRINTcircleSIZE * sizeof(cl_object)); \ + CIRCLElimit = &CIRCLEbase[size]; \ + setupPRINTcircle1(x); } +#endif DOWN_STACK + + + +static void +setupPRINTcircle1(cl_object x) +{ cl_object *vp, *vq; + + CIRCLEtop = CIRCLEbase; + travel_push_object(x); + /* compact shared elements towards CIRCLEbase */ + for (vp = vq = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (vp[1] != Cnil) { + vq[0] = vp[0]; vq[1] = Cnil; vq += 2; + } + CIRCLEtop = vq; +} + +static void +travel_push_object(cl_object x) +{ + enum type t; + cl_index i; + cl_object *vp; + + cs_check(x); + +BEGIN: + if (x == OBJNULL) return; + t = type_of(x); + if (t != t_array && t != t_vector && t != t_cons && +#ifdef CLOS + t != t_instance && +#else + t != t_structure && +#endif CLOS + !(t == t_symbol && Null(x->symbol.hpack))) + return; + for (vp = CIRCLEbase; vp < CIRCLEtop; vp += 2) + if (x == *vp) { + /* if (vp[1] == Cnil) */ vp[1] = Ct; + return; + } + if (CIRCLEtop >= CIRCLElimit) + ecls_longjmp(CIRCLEjmp, 1); /* go back to allocate more space */ + CIRCLEtop[0] = x; + CIRCLEtop[1] = Cnil; + CIRCLEtop += 2; + + switch (t) { + case t_array: + if ((enum aelttype)x->array.elttype == aet_object) + for (i = 0; i < x->array.dim; i++) + travel_push_object(x->array.self.t[i]); + break; + + case t_vector: + if ((enum aelttype)x->vector.elttype == aet_object) + for (i = 0; i < x->vector.fillp; i++) + travel_push_object(x->vector.self.t[i]); + break; + + case t_cons: + travel_push_object(CAR(x)); + x = CDR(x); + goto BEGIN; + +#ifdef CLOS + case t_instance: + for (i = 0; i < x->instance.length; i++) + travel_push_object(x->instance.slots[i]); + break; +#else + case t_structure: + for (i = 0; i < x->str.length; i++) + travel_push_object(x->str.self[i]); +#endif CLOS + default: + /* INV: all types of 'x' have been handled */ + } +} + +void setupPRINT(cl_object x, cl_object strm) +{ + cl_object y; + + PRINTstream = strm; +RETRY: if (type_of(PRINTstream) == t_stream) { + if (PRINTstream->stream.mode == (short)smm_synonym) { + PRINTstream = symbol_value(PRINTstream->stream.object0); + goto RETRY; + } + else + output_ch_fun = writec_PRINTstream; + } else +#ifdef CLOS + if (type_of(PRINTstream) == t_instance) + output_ch_fun = interactive_writec_PRINTstream; + else +#endif CLOS + { SYM_VAL(Vstandard_output) = symbol_value(Vterminal_io); + FEwrong_type_argument(Sstream, PRINTstream); + } + PRINTescape = symbol_value(Vprint_escape) != Cnil; + PRINTpretty = symbol_value(Vprint_pretty) != Cnil; + PRINTcircle = symbol_value(Vprint_circle) != Cnil; + y = symbol_value(Vprint_base); + if (!FIXNUMP(y) || fix(y) < 2 || fix(y) > 36) { + SYM_VAL(Vprint_base) = MAKE_FIXNUM(10); + FEerror("~S is an illegal PRINT-BASE.", 1, y); + } else + PRINTbase = fix(y); + PRINTradix = symbol_value(Vprint_radix) != Cnil; + PRINTcase = symbol_value(Vprint_case); + if (PRINTcase != Kupcase && PRINTcase != Kdowncase && + PRINTcase != Kcapitalize) { + SYM_VAL(Vprint_case) = Kdowncase; + FEerror("~S is an illegal PRINT-CASE.", 1, PRINTcase); + } + PRINTgensym = symbol_value(Vprint_gensym) != Cnil; + y = symbol_value(Vprint_level); + if (Null(y)) + PRINTlevel = -1; + else if (!FIXNUMP(y) || fix(y) < 0) { + SYM_VAL(Vprint_level) = Cnil; + FEerror("~S is an illegal PRINT-LEVEL.", 1, y); + } else + PRINTlevel = fix(y); + y = symbol_value(Vprint_length); + if (Null(y)) + PRINTlength = -1; + else if (!FIXNUMP(y) || fix(y) < 0) { + SYM_VAL(Vprint_length) = Cnil; + FEerror("~S is an illegal PRINT-LENGTH.", 1, y); + } else + PRINTlength = fix(y); + PRINTarray = symbol_value(Vprint_array) != Cnil; +/* setupPRINTcircle(x); */ + if (PRINTpretty) { + qh = qt = qc = 0; + isp = iisp = 0; + indent_stack[0] = 0; + write_ch_fun = writec_queue; + } else + write_ch_fun = output_ch_fun; + PRINTpackage = symbol_value(siVprint_package); + if (PRINTpackage == Cnil) PRINTpackage = OBJNULL; + PRINTstructure = symbol_value(siVprint_structure) != Cnil; +} + +void cleanupPRINT(void) +{ + if (PRINTpretty) + flush_queue(TRUE); +} + +bool +potential_number_p(cl_object strng, int base) +{ + int i, l, c; bool dc; + char *s; + + l = strng->string.fillp; + if (l == 0) + return(FALSE); + s = strng->string.self; + dc = FALSE; + c = s[0]; + if (digitp(c, base) >= 0) + dc = TRUE; + else if (c != '+' && c != '-' && c != '^' && c != '_') + return(FALSE); + if (s[l-1] == '+' || s[l-1] == '-') + return(FALSE); + for (i = 1; i < l; i++) { + c = s[i]; + if (digitp(c, base) >= 0) { + dc = TRUE; + continue; + } + if (c != '+' && c != '-' && c != '/' && c != '.' && + c != '^' && c != '_' && + c != 'e' && c != 'E' && + c != 's' && c != 'S' && c != 'l' && c != 'L') + return(FALSE); + } + return(dc); +} + +@(defun write (x + &key ((:stream strm) Cnil) + (escape symbol_value(Vprint_escape)) + (radix symbol_value(Vprint_radix)) + (base symbol_value(Vprint_base)) + (circle symbol_value(Vprint_circle)) + (pretty symbol_value(Vprint_pretty)) + (level symbol_value(Vprint_level)) + (length symbol_value(Vprint_length)) + ((:case cas) symbol_value(Vprint_case)) + (gensym symbol_value(Vprint_gensym)) + (array symbol_value(Vprint_array))) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + output_ch_fun = writec_PRINTstream; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + output_ch_fun = interactive_writec_PRINTstream; + else +#endif CLOS + FEtype_error_stream(strm); + PRINTstream = strm; + PRINTescape = escape != Cnil; + PRINTpretty = pretty != Cnil; + PRINTcircle = circle != Cnil; + if (!FIXNUMP(base) || fix((base))<2 || fix((base))>36) + FEerror("~S is an illegal PRINT-BASE.", 1, base); + else + PRINTbase = fix((base)); + PRINTradix = radix != Cnil; + PRINTcase = cas; + if (PRINTcase != Kupcase && PRINTcase != Kdowncase && + PRINTcase != Kcapitalize) + FEerror("~S is an illegal PRINT-CASE.", 1, cas); + PRINTgensym = gensym != Cnil; + if (Null(level)) + PRINTlevel = -1; + else if (!FIXNUMP(level) || fix((level)) < 0) + FEerror("~S is an illegal PRINT-LEVEL.", 1, level); + else + PRINTlevel = fix((level)); + if (Null(length)) + PRINTlength = -1; + else if (!FIXNUMP(length) || fix((length)) < 0) + FEerror("~S is an illegal PRINT-LENGTH.", 1, length); + else + PRINTlength = fix((length)); + PRINTarray = array != Cnil; + if (PRINTpretty) { + qh = qt = qc = 0; + isp = iisp = 0; + indent_stack[0] = 0; + write_ch_fun = writec_queue; + } else + write_ch_fun = output_ch_fun; + PRINTpackage = symbol_value(siVprint_package); + if (PRINTpackage == Cnil) PRINTpackage = OBJNULL; + PRINTstructure = symbol_value(siVprint_structure) != Cnil; + setupPRINTcircle(x); + write_object(x, 0); + cleanupPRINT(); + FLUSH_STREAM(PRINTstream); + @(return x) +@) + +@(defun prin1 (obj &optional strm) +@ + prin1(obj, strm); + @(return obj) +@) + +@(defun print (obj &optional strm) +@ + print(obj, strm); + @(return obj) +@) + +@(defun pprint (obj &optional strm) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + output_ch_fun = writec_PRINTstream; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + output_ch_fun = interactive_writec_PRINTstream; + else +#endif CLOS + FEtype_error_stream(strm); + setupPRINT(obj, strm); + PRINTescape = TRUE; + PRINTpretty = TRUE; + qh = qt = qc = 0; + isp = iisp = 0; + indent_stack[0] = 0; + write_ch_fun = writec_queue; + output_ch('\n'); + setupPRINTcircle(obj); + write_object(obj, 0); + cleanupPRINT(); + FLUSH_STREAM(PRINTstream); + @(return) +@) + +@(defun princ (obj &optional strm) +@ + princ(obj, strm); + @(return obj) +@) + +@(defun write_char (c &optional strm) +@ + /* INV: char_code() checks the type of `c' */ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + writec_stream(char_code(c), strm); +/* + FLUSH_STREAM(strm); +*/ + @(return c) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) { + interactive_writec_stream(char_code(c), strm); + @(return c) + } + else +#endif + FEtype_error_stream(strm); +@) + +@(defun write_string (strng &o strm &k (start MAKE_FIXNUM(0)) end) + cl_index s, e, i; +@ + get_string_start_end(strng, start, end, &s, &e); + assert_type_string(strng); + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + for (i = s; i < e; i++) + writec_stream(strng->string.self[i], strm); + flush_stream(strm); + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + funcall(4, Sstream_write_string, strm, strng, + MAKE_FIXNUM(s), MAKE_FIXNUM(e)); + else +#endif + FEtype_error_stream(strm); + @(return strng) +@) + +@(defun write_line (strng &o strm &k (start MAKE_FIXNUM(0)) end) + cl_index s, e, i; +@ + get_string_start_end(strng, start, end, &s, &e); + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + assert_type_string(strng); + +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + for (i = s; i < e; i++) + writec_stream(strng->string.self[i], strm); + writec_stream('\n', strm); + flush_stream(strm); + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) { + for (i = s; i < e; i++) + interactive_writec_stream(strng->string.self[i], strm); + interactive_writec_stream('\n', strm); + flush_interactive_stream(strm); + } else +#endif CLOS + FEtype_error_stream(strm); + @(return strng) +@) + +@(defun terpri (&optional strm) +@ + terpri(strm); + @(return Cnil) +@) + +@(defun fresh_line (&optional strm) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + if (FILE_COLUMN(strm) == 0) + @(return Cnil) + writec_stream('\n', strm); + flush_stream(strm); + @(return Ct) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(2, Sstream_fresh_line,strm); + else +#endif + FEtype_error_stream(strm); +@) + +@(defun force_output (&o strm) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + flush_stream(strm); + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + flush_interactive_stream(strm); + else +#endif CLOS + FEtype_error_stream(strm); + @(return Cnil) +@) + +@(defun clear_output (&o strm) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + clear_output_stream(strm); + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + funcall(2, Sstream_clear_output, strm); + else +#endif + FEtype_error_stream(strm); + @(return Cnil) +@) + +@(defun write_byte (integer binary_output_stream) +@ + if (!FIXNUMP(integer)) + FEerror("~S is not a byte.", 1, integer); + assert_type_stream(binary_output_stream); + writec_stream(fix(integer), binary_output_stream); + @(return integer) +@) + +@(defun write_bytes (stream string start end) + cl_index is, ie; FILE *fp; + int written, sofarwritten, towrite; +@ + assert_type_stream(stream); + if (stream->stream.mode == smm_closed) + closed_stream(stream); + + is = fix(start); /* FIXME: Unsafe! */ + ie = fix(end); + sofarwritten = is; + towrite = ie-is; + fp = stream->stream.file; + if (fp == NULL) fp = stream->stream.object1->stream.file; + while (towrite > 0) { + written = write(fileno(fp), + string->string.self+sofarwritten, towrite); + if (written != -1) { + towrite -= written; + sofarwritten += written; + } + else @(return MAKE_FIXNUM(-1)) + } + @(return MAKE_FIXNUM(sofarwritten - is)) +@) + +void +init_print(void) +{ + SYM_VAL(Vprint_escape) = Ct; + SYM_VAL(Vprint_pretty) = Ct; + SYM_VAL(Vprint_circle) = Cnil; + SYM_VAL(Vprint_base) = MAKE_FIXNUM(10); + SYM_VAL(Vprint_radix) = Cnil; + SYM_VAL(Vprint_case) = Kupcase; + SYM_VAL(Vprint_gensym) = Ct; + SYM_VAL(Vprint_level) = Cnil; + SYM_VAL(Vprint_length) = Cnil; + SYM_VAL(Vprint_array) = Ct; + + SYM_VAL(siVprint_package) = Cnil; + SYM_VAL(siVprint_structure) = Cnil; + + PRINTstream = Cnil; + register_root(&PRINTstream); + PRINTescape = TRUE; + PRINTpretty = FALSE; + PRINTcircle = FALSE; + PRINTbase = 10; + PRINTradix = FALSE; + PRINTcase = Kupcase; + register_root(&PRINTcase); + PRINTgensym = TRUE; + PRINTlevel = -1; + PRINTlength = -1; + PRINTarray = FALSE; + + write_ch_fun = writec_PRINTstream; + output_ch_fun = writec_PRINTstream; +} + +cl_object +princ(cl_object obj, cl_object strm) +{ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + if (obj == OBJNULL) + goto SIMPLE_CASE; + switch (type_of(obj)) { + case t_symbol: + PRINTcase = symbol_value(Vprint_case); + PRINTpackage = symbol_value(siVprint_package); + if (PRINTpackage == Cnil) PRINTpackage = OBJNULL; + + SIMPLE_CASE: + case t_string: + case t_character: + PRINTstream = strm; + PRINTescape = FALSE; +RETRY: if (type_of(PRINTstream) == t_stream) { + if (PRINTstream->stream.mode == (short)smm_synonym) { + PRINTstream = symbol_value(PRINTstream->stream.object0); + goto RETRY; + } + else + write_ch_fun = writec_PRINTstream; + } else +#ifdef CLOS + if (type_of(PRINTstream) == t_instance) + write_ch_fun = interactive_writec_PRINTstream; + else +#endif CLOS + FEtype_error_stream(strm); + write_object(obj, 0); + break; + + default: + setupPRINT(obj, strm); + PRINTescape = FALSE; + write_object(obj, 0); + cleanupPRINT(); + } + return(obj); +} + +cl_object +prin1(cl_object obj, cl_object strm) +{ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + if (obj == OBJNULL) + goto SIMPLE_CASE; + switch (type_of(obj)) { + SIMPLE_CASE: + case t_string: + case t_character: + PRINTstream = strm; + PRINTescape = TRUE; +RETRY: if (type_of(PRINTstream) == t_stream) { + if (PRINTstream->stream.mode == (short)smm_synonym) { + PRINTstream = symbol_value(PRINTstream->stream.object0); + goto RETRY; + } + else + write_ch_fun = writec_PRINTstream; + } else +#ifdef CLOS + if (type_of(PRINTstream) == t_instance) + write_ch_fun = interactive_writec_PRINTstream; + else +#endif CLOS + FEtype_error_stream(strm); + write_object(obj, 0); + break; + + default: + setupPRINT(obj, strm); + PRINTescape = TRUE; + setupPRINTcircle(obj); + write_object(obj, 0); + cleanupPRINT(); + } + FLUSH_STREAM(PRINTstream); + return(obj); +} + +cl_object +print(cl_object obj, cl_object strm) +{ + terpri(strm); + prin1(obj, strm); + princ_char(' ', strm); + return obj; +} + +cl_object +terpri(cl_object strm) +{ + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + write_ch_fun = writec_stream; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + write_ch_fun = interactive_writec_stream; + else +#endif CLOS + FEtype_error_stream(strm); + write_ch('\n', strm); + FLUSH_STREAM(strm); + return(Cnil); +} + +void +write_string(cl_object strng, cl_object strm) +{ + cl_index i; + + if (Null(strm)) + strm = symbol_value(Vstandard_output); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + assert_type_string(strng); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + for (i = 0; i < strng->string.fillp; i++) + writec_stream(strng->string.self[i], strm); + flush_stream(strm); + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) { + for (i = 0; i < strng->string.fillp; i++) + interactive_writec_stream(strng->string.self[i], strm); + flush_interactive_stream(strm); + } else +#endif CLOS + FEtype_error_stream(strm); +} + +/* + THE ULTRA-SPECIAL-DINNER-SERVICE OPTIMIZATION +*/ +void +princ_str(const char *s, cl_object sym) +{ +/* sym = symbol_value(sym); Beppe */ + if (Null(sym)) + sym = symbol_value(Vstandard_output); + else if (sym == Ct) + sym = symbol_value(Vterminal_io); +RETRY: if (type_of(sym) == t_stream) { + if (sym->stream.mode == (short)smm_synonym) { + sym = symbol_value(sym->stream.object0); + goto RETRY; + } + else + writestr_stream(s, sym); + } else +#ifdef CLOS + if (type_of(sym) == t_instance) + while (*s != '\0') + interactive_writec_stream(*s++, sym); + else +#endif CLOS + FEerror("~S is not a stream.", 1, sym); +} + +void +princ_char(int c, cl_object sym) +{ +/* sym = symbol_value(sym); Beppe */ + if (Null(sym)) + sym = symbol_value(Vstandard_output); + else if (sym == Ct) + sym = symbol_value(Vterminal_io); +RETRY: if (type_of(sym) == t_stream) { + if (sym->stream.mode == (short)smm_synonym) { + sym = symbol_value(sym->stream.object0); + goto RETRY; + } + else { + writec_stream(c, sym); + if (c == '\n') + flush_stream(sym); + } + } else +#ifdef CLOS + if (type_of(sym) == t_instance) { + interactive_writec_stream(c, sym); + if (c == '\n') + flush_interactive_stream(sym); + } else +#endif CLOS + FEerror("~S is not a stream.", 1, sym); +} diff --git a/src/c/profile.d b/src/c/profile.d new file mode 100644 index 000000000..511a04145 --- /dev/null +++ b/src/c/profile.d @@ -0,0 +1,137 @@ +/* profile.c -- profiling tool */ +/* + Copyright (c) 1996, Giuseppe Attardi. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +/* + *---------------------------------------------------------------------- + * Profiling tool + * ---------------------------------------------------------------------- + */ + +extern caddr_t *function_entry_table; +extern int function_entries; + +static object sSAprofile_arrayA; +static caddr_t profile_start; +static unsigned int profile_scale; + +/* + *---------------------------------------------------------------------- + * profile resolution start-address + * scale is a value between 0 and 16384: + * 0 means stop profiling, other values represent the size of + * consecutive groups of instructions to which each tick is attributed + * Only (length *profile-array*) / (2 * scale) intructions from + * start-address are profiled. + *---------------------------------------------------------------------- + */ + +extern int siLmake_vector (int narg, object etype, object dim, object adj, object fillp, object displ, object disploff, object staticp); +extern void profil (short unsigned int *, size_t, int, unsigned int); + +siLprofile(int narg, object scale, object start_address) +{ + int size; + object ar = sSAprofile_arrayA->symbol.dbind; + if ((narg > 2) || (narg == 0)) + check_arg_failed(narg, 2); + if (narg == 1) + profile_start = (caddr_t)function_entry_table[0]; + else + profile_start = (caddr_t)fixnnint(start_address); + profile_scale = fixnnint(scale); + if (type_of(ar) != t_vector) { + size = (int)function_entry_table[(function_entries-1)*2] + - (int)profile_start; + size = size / (sizeof(int) * 2 * profile_scale); + ar = siLmake_vector(7, Sfixnum, MAKE_FIXNUM(size), + Cnil, Cnil, Cnil, Cnil, + Ct); /* static: must not be moved by GC */ + sSAprofile_arrayA->symbol.dbind = ar; + } + else +# define inheap(pp) ((unsigned long)(pp) < (unsigned long)heap_end) + if (!inheap(ar->array.self.fix)) + FEerror("SI:*PROFILE-ARRAY* must be a static array", 0); + if (profile_scale > 0) + profile_scale = 65536 / ( 2 * profile_scale); + profil((unsigned short *)ar->array.self.fix, ar->array.dim * sizeof(int), + profile_start, profile_scale); +#error "Not fixed" + VALUES(0) = MAKE_FIXNUM(profile_start); + RETURN(1); +} + +siLclear_profile(int narg) +{ + int i; + object ar = sSAprofile_arrayA->symbol.dbind; + check_arg(0); + if (type_of(ar) != t_vector) + FEerror("SI:*PROFILE-ARRAY* must be an array of FIXNUM", 0); + for (i = 0; i < ar->array.dim; i++) + ar->array.self.fix[i] = 0; +} + +total_ticks(unsigned short *aar, unsigned int dim) +{ + register unsigned short *endar = aar+dim; + register int count = 0; + for ( ; aar < endar; aar++) + count += *aar; + return count; +} + +siLdisplay_profile(int narg) +{ + caddr_t prev, next; + unsigned upto, dim; + int i, j, scale, count, total; + unsigned short *ar; + object obj_ar = sSAprofile_arrayA->symbol.dbind; + int groupSize = 0x20000 / profile_scale; + + check_arg(0); + if (type_of(obj_ar) != t_vector) + FEerror("si:*profile-array* not a vector", 0); + ar = (unsigned short *)obj_ar->array.self.fix; + dim = obj_ar->array.dim * (sizeof(int) / sizeof(short)); + + total = total_ticks(ar, dim); + + for (i = 0; i < 2*function_entries; i += 2, prev = next) { + prev = function_entry_table[i]; + if (prev < profile_start) continue; + + if (i+2 == 2*function_entries) + upto = dim; + else { + next = function_entry_table[i+2]; + upto = (next > profile_start) + ? (next - profile_start) / groupSize : 0; + if (upto >= dim) upto = dim; + } + count = 0; + for (j = (prev - profile_start) / groupSize; j < upto; j++) + count += ar[j]; + if (count > 0) { + object name = (object)function_entry_table[i+1]; + printf("\n%6.2f%% (%5d): ", 100.0 * count/total, count); + prin1(name, Cnil); + fflush(stdout); + } + if (upto == dim) break; + } + printf("\nTotal ticks: %d\n", total); fflush(stdout); + RETURN(0); +} diff --git a/src/c/read.d b/src/c/read.d new file mode 100644 index 000000000..52c77703d --- /dev/null +++ b/src/c/read.d @@ -0,0 +1,2405 @@ +/* + read.d -- Read. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" +#include + +/******************************* EXPORTS ******************************/ + +cl_object standard_readtable; + +cl_object Vreadtable; +cl_object Vread_default_float_format; +cl_object Vread_base; +cl_object Vread_suppress; + +cl_object Kjunk_allowed; + +cl_object siSsharp_comma; + +#ifndef THREADS +cl_object READtable; +int READdefault_float_format; +int READbase; +bool READsuppress; +bool preserving_whitespace_flag; +bool escape_flag; +cl_object delimiting_char; +bool detect_eos_flag; +bool in_list_flag; +bool dot_flag; +cl_object default_dispatch_macro; +cl_object sharp_eq_context; +cl_object (*read_ch_fun)() = readc; +#endif THREADS + +#ifdef CLOS +cl_object Sstream_read_line, + Sstream_read_char, + Sstream_unread_char, + Sstream_peek_char, + Sstream_listen, + Sstream_clear_input; +#endif + +/******************************* ------- ******************************/ + +static cl_object dispatch_reader; + +#define token_buffer cl_token->string.self + +#define cat(c) (READtable->readtable.table[char_code((c))].syntax_type) + +static void too_long_token (void); +static void too_long_string (void); +static void extra_argument (int c, cl_object d); + +static void +setup_READtable(void) +{ + READtable = current_readtable(); +} + +static void +setup_READ(void) +{ + cl_object x; + + READtable = current_readtable(); + x = symbol_value(Vread_default_float_format); + if (x == Ssingle_float || x == Sshort_float) + READdefault_float_format = 'S'; + else if (x == Sdouble_float || x == Slong_float) + READdefault_float_format = 'F'; + else { + SYM_VAL(Vread_default_float_format) = Ssingle_float; + FEerror("The value of *READ-DEFAULT-FLOAT-FORMAT*, ~S, was illegal.", + 1, x); + } + x = symbol_value(Vread_base); + if (!FIXNUMP(x) || fix(x) < 2 || fix(x) > 36) { + SYM_VAL(Vread_base) = MAKE_FIXNUM(10); + FEerror("The value of *READ-BASE*, ~S, was illegal.", 1, x); + } + READbase = fix(x); + READsuppress = symbol_value(Vread_suppress) != Cnil; +} + +static void +setup_standard_READ(void) +{ + READtable = standard_readtable; + READdefault_float_format = 'S'; + READbase = 10; + READsuppress = FALSE; + sharp_eq_context = Cnil; + backq_level = 0; +} + +#ifdef CLOS +cl_object +interactive_readc(cl_object stream) +{ + return _funcall(2, Sstream_read_char, stream); +} +#endif CLOS + +cl_object +readc(cl_object in) +{ + return(code_char(readc_stream(in))); +} + +#define read_char(in) (*read_ch_fun)(in) + +void unread_char(cl_object c, cl_object in) +{ + /* INV: char_code() checks the type of `c' */ +#ifdef CLOS + if (type_of(in) == t_instance) + funcall(3, Sstream_unread_char, in, c); + else +#endif + unreadc_stream(char_code(c), in); +} + +/* + peek_char corresponds to COMMON Lisp function PEEK-CHAR. + When pt is TRUE, preceeding whitespaces are ignored. +*/ +cl_object +peek_char(bool pt, cl_object in) +{ + cl_object c; + + c = read_char(in); + if (pt) + while (cat(c) == cat_whitespace) + c = read_char(in); + unread_char(c, in); + return(c); +} + +static cl_object +read_object_recursive(cl_object in) +{ + volatile cl_object x; + bool e; + + cl_object old_READtable = READtable; + int old_READdefault_float_format = READdefault_float_format; + int old_READbase = READbase; + bool old_READsuppress = READsuppress; + + if (frs_push(FRS_PROTECT, Cnil)) + e = TRUE; + else { + setup_READ(); + x = read_object(in); + e = FALSE; + } + frs_pop(); + + READtable = old_READtable; + READdefault_float_format = old_READdefault_float_format; + READbase = old_READbase; + READsuppress = old_READsuppress; + + if (e) unwind(nlj_fr, nlj_tag); + return(x); +} + +cl_object +read_object_non_recursive(cl_object in) +{ + volatile cl_object x; + bool e; + cl_object old_READtable; + int old_READdefault_float_format; + int old_READbase; + int old_READsuppress; + int old_backq_level; + cl_object old_sharp_eq_context; + + old_READtable = READtable; + old_READdefault_float_format = READdefault_float_format; + old_READbase = READbase; + old_READsuppress = READsuppress; + old_sharp_eq_context = sharp_eq_context; + old_backq_level = backq_level; + setup_READ(); + sharp_eq_context = Cnil; + backq_level = 0; + + if (frs_push(FRS_PROTECT, Cnil)) + e = TRUE; + else { + static cl_object patch_sharp(cl_object x); + e = FALSE; + x = read_object(in); + if (!Null(sharp_eq_context)) + x = patch_sharp(x); + } + frs_pop(); + + READtable = old_READtable; + READdefault_float_format = old_READdefault_float_format; + READbase = old_READbase; + READsuppress = old_READsuppress; + sharp_eq_context = old_sharp_eq_context; + backq_level = old_backq_level; + if (e) unwind(nlj_fr, nlj_tag); + return(x); +} + +#if TK +extern bool no_input; +#define GETC(c, fp) { if (fp == stdin) \ + while (no_input) Tk_DoOneEvent(0); \ + c = getc(fp); \ + no_input = !FILE_CNT(fp); } +#else +#define GETC(c, fp) c = getc(fp) +#endif /* TK */ + +/* Beppe: faster code for inner loop from file stream */ +#if !defined(CLOS) +#define READ_CHAR_TO(res, in, eof_code) \ + {FILE *fp = in->stream.file; \ + if (fp) { int ch; \ + GETC(ch, fp); \ + if (ch == EOF) \ + {eof_code;} \ + else res = code_char(ch);} \ + else \ + if (stream_at_end(in)) \ + {eof_code;} \ + else res = read_char(in);} +#else +#define READ_CHAR_TO(res, in, eof_code) \ + {if (stream_at_end(in)) {eof_code;} else res = read_char(in);} +#endif unix + +/* + Read_object(in) reads an object from stream in. + This routine corresponds to COMMON Lisp function READ. +*/ +cl_object +read_object(cl_object in) +{ + cl_object x, c; + enum chattrib a; + cl_object old_delimiter, p; + cl_index length, i, colon; + int colon_type; + bool df, ilf; + + cs_check(in); + + old_delimiter = delimiting_char; + delimiting_char = OBJNULL; + df = detect_eos_flag; + detect_eos_flag = FALSE; + ilf = in_list_flag; + in_list_flag = FALSE; + dot_flag = FALSE; + +BEGIN: + /* Beppe: */ + do { + READ_CHAR_TO(c, in, if (df) return(OBJNULL); + else + FEend_of_file(in)); + a = cat(c); + } while (a == cat_whitespace); + delimiting_char = OBJNULL; + if (old_delimiter != OBJNULL && old_delimiter == c) + return(OBJNULL); + if (a == cat_terminating || a == cat_non_terminating) { + cl_object x = READtable->readtable.table[char_code(c)].macro; + cl_object o = _funcall(3, x, in, c); + if (NValues == 0) goto BEGIN; + if (NValues > 1) FEerror("The readmacro ~S returned ~D values.", + 2, x, MAKE_FIXNUM(i)); + return o; + } + escape_flag = FALSE; + length = 0; + colon_type = 0; + for (;;) { + if (a == cat_single_escape) { + c = read_char(in); + a = cat_constituent; + escape_flag = TRUE; + } else if (a == cat_multiple_escape) { + escape_flag = TRUE; + for (;;) { + if (stream_at_end(in)) + FEend_of_file(in); + c = read_char(in); + a = cat(c); + if (a == cat_single_escape) { + c = read_char(in); + a = cat_constituent; + } else if (a == cat_multiple_escape) + break; + if (length >= cl_token->string.dim) + too_long_token(); + token_buffer[length++] = char_code(c); + } + goto NEXT; + } else if ('a' <= char_code(c) && char_code(c) <= 'z') + c = code_char(toupper(char_code(c))); + else if (char_code(c) == ':') { + if (colon_type == 0) { + colon_type = 1; + colon = length; + } else if (colon_type == 1 && colon == length-1) + colon_type = 2; + else + colon_type = -1; + /* Colon has appeared twice. */ + } + if (a == cat_whitespace || a == cat_terminating) { + if (preserving_whitespace_flag || + cat(c) != cat_whitespace) + unread_char(c, in); + break; + } + if (length >= cl_token->string.dim) + too_long_token(); + token_buffer[length++] = char_code(c); + NEXT: + READ_CHAR_TO(c, in, break); + a = cat(c); + } + + if (READsuppress) { + cl_token->string.fillp = length; + return(Cnil); + } + if (ilf && !escape_flag && + length == 1 && cl_token->string.self[0] == '.') { + dot_flag = TRUE; + return(Cnil); + } else if (!escape_flag && length > 0) { + for (i = 0; i < length; i++) + if (cl_token->string.self[i] != '.') + goto N; + FEerror("Dots appeared illegally.", 0); + } + +N: + cl_token->string.fillp = length; + if (escape_flag || (READbase <= 10 && token_buffer[0] > '9')) + goto SYMBOL; + x = parse_number(token_buffer, length, &i, READbase); + if (x != OBJNULL && length == i) + return(x); + +SYMBOL: + if (colon_type == 1 /* && length > colon + 1 */) { + if (colon == 0) + p = keyword_package; + else { + cl_token->string.fillp = colon; + p = find_package(cl_token); + if (Null(p)) + FEerror("There is no package with the name ~A.", + 1, copy_simple_string(cl_token)); + } + for (i = colon + 1; i < length; i++) + token_buffer[i - (colon + 1)] + = token_buffer[i]; + cl_token->string.fillp = length - (colon + 1); + if (colon > 0) { + cl_token->string.self[cl_token->string.fillp] = '\0'; + x = find_symbol(cl_token, p); + if (intern_flag != EXTERNAL) + FEerror("Cannot find the external symbol ~A in ~S.", + 2, copy_simple_string(cl_token), p); + return(x); + } + } else if (colon_type == 2 /* && colon > 0 && length > colon + 2 */) { + cl_token->string.fillp = colon; + p = find_package(cl_token); + if (Null(p)) + FEerror("There is no package with the name ~A.", + 1, copy_simple_string(cl_token)); + for (i = colon + 2; i < length; i++) + token_buffer[i - (colon + 2)] = token_buffer[i]; + cl_token->string.fillp = length - (colon + 2); + } else + p = current_package(); + token_buffer[cl_token->string.fillp] = '\0'; + x = intern(cl_token, p); + if (x->symbol.name == cl_token) + x->symbol.name = copy_simple_string(cl_token); + return(x); +} + +#define is_exponent_marker(i) \ + ((i) == 'e' || (i) == 'E' || \ + (i) == 's' || (i) == 'S' || (i) == 'f' || (i) == 'F' || \ + (i) == 'd' || (i) == 'D' || (i) == 'l' || (i) == 'L' || \ + (i) == 'b' || (i) == 'B') + +#define basep(d) (d <= 36) + +/* + parse_number(s, end, ep, radix) parses C string s + up to (but not including) s[end] + using radix as the radix for the rational number. + (For floating numbers, radix should be 10.) + When parsing succeeds, + the index of the next character is assigned to *ep, + and the number is returned as a lisp data object. + If not, OBJNULL is returned. +*/ +cl_object +parse_number(char *s, cl_index end, cl_index *ep, int radix) +{ + cl_object x, y; + int sign; + cl_object integer_part; + double fraction, fraction_unit, f; + char exponent_marker; + int exponent, d; + cl_index i, j, k; + + if (s[end-1] == '.') + radix = 10; + /* + DIRTY CODE!! + */ +BEGIN: + exponent_marker = 'E'; + i = 0; + sign = 1; + if (s[i] == '+') + i++; + else if (s[i] == '-') { + sign = -1; + i++; + } + integer_part = big_register0_get(); + if (i >= end) + goto NO_NUMBER; + if (s[i] == '.') { + if (radix != 10) { + radix = 10; + goto BEGIN; + } + i++; + goto FRACTION; + } + if (!basep(radix) || (d = digitp(s[i], radix)) < 0) + goto NO_NUMBER; + do { + big_mul_ui(integer_part, radix); + big_add_ui(integer_part, d); + i++; + } while (i < end && (d = digitp(s[i], radix)) >= 0); + if (i >= end) + goto MAKE_INTEGER; + if (s[i] == '.') { + if (radix != 10) { + radix = 10; + goto BEGIN; + } + if (++i >= end) + goto MAKE_INTEGER; + else if (digitp(s[i], radix) >= 0) + goto FRACTION; + else if (is_exponent_marker(s[i])) { + fraction = (double)sign * big_to_double(integer_part); + goto EXPONENT; + } else + goto MAKE_INTEGER; + } + if (s[i] == '/') { + i++; + if (sign < 0) + big_complement(integer_part); + x = big_register_normalize(integer_part); + + /* DENOMINATOR */ + + if ((d = digitp(s[i], radix)) < 0) + goto NO_NUMBER; + integer_part = big_register0_get(); + do { + big_mul_ui(integer_part, radix); + big_add_ui(integer_part, d); + i++; + } while (i < end && (d = digitp(s[i], radix)) >= 0); + y = big_register_normalize(integer_part); + x = make_ratio(x, y); + goto END; + } + + if (is_exponent_marker(s[i])) { + fraction = (double)sign * big_to_double(integer_part); + goto EXPONENT; + } + + goto NO_NUMBER; + +MAKE_INTEGER: + if (sign < 0) + big_complement(integer_part); + x = big_register_normalize(integer_part); + goto END; + +FRACTION: + + if (radix != 10) + goto NO_NUMBER; + + radix = 10; + if ((d = digitp(s[i], radix)) < 0) + goto NO_NUMBER; + fraction = 0.0; + fraction_unit = 1000000000.0; + for (;;) { + k = j = 0; + do { + j = 10*j + d; + i++; + k++; + if (i < end) + d = digitp(s[i], radix); + else + break; + } while (k < 9 && d >= 0); + while (k++ < 9) + j *= 10; + fraction += ((double)j /fraction_unit); + if (i >= end || d < 0) + break; + fraction_unit *= 1000000000.0; + } + fraction += big_to_double(integer_part); + fraction *= (double)sign; + if (i >= end) + goto MAKE_FLOAT; + if (is_exponent_marker(s[i])) + goto EXPONENT; + goto MAKE_FLOAT; + +EXPONENT: + + if (radix != 10) + goto NO_NUMBER; + + radix = 10; + exponent_marker = s[i]; + i++; + if (i >= end) + goto NO_NUMBER; + sign = 1; + if (s[i] == '+') + i++; + else if (s[i] == '-') { + sign = -1; + i++; + } + if (i >= end) + goto NO_NUMBER; + if ((d = digitp(s[i], radix)) < 0) + goto NO_NUMBER; + exponent = 0; + do { + exponent = 10 * exponent + d; + i++; + } while (i < end && (d = digitp(s[i], radix)) >= 0); + d = exponent; + f = 10.0; + /* Use pow because it is more accurate */ + { + double pow(double, double); + double po = pow(10.0, (double)(sign * d)); + if (po == 0.0) { + fraction *= pow(10.0, (double)(sign * (d-1))); + fraction /= 10.0; + } else + fraction *= po; + } + +MAKE_FLOAT: + switch (exponent_marker) { + + case 'e': case 'E': + exponent_marker = READdefault_float_format; + goto MAKE_FLOAT; + + case 's': case 'S': +#ifdef IEEEFLOAT + { + float biggest_float; + *((int *)&biggest_float) = 0x7f7fffff; + if (fraction > biggest_float || fraction < -biggest_float) + FEerror("Floating-point overflow.", 0); + } +#endif + x = make_shortfloat((float)fraction); + break; + + case 'f': case 'F': case 'd': case 'D': case 'l': case 'L': +#ifdef IEEEFLOAT + if ((*((int *)&fraction + HIND) & 0x7ff00000) == 0x7ff00000) + FEerror("Floating-point overflow.", 0); +#endif + x = make_longfloat((double)fraction); + break; + + case 'b': case 'B': + goto NO_NUMBER; + } + +END: + *ep = i; + return(x); + +NO_NUMBER: + *ep = i; + return(OBJNULL); +} + +cl_object +parse_integer(char *s, cl_index end, cl_index *ep, int radix) +{ + cl_object x; + int sign, d; + cl_object integer_part; + cl_index i; + + i = 0; + sign = 1; + if (s[i] == '+') + i++; + else if (s[i] == '-') { + sign = -1; + i++; + } + if (i >= end || !basep(radix) || (d = digitp(s[i], radix)) < 0) { + *ep = i; + return(OBJNULL); + } + integer_part = big_register0_get(); + do { + big_mul_ui(integer_part, radix); + big_add_ui(integer_part, d); + i++; + } while (i < end && (d = digitp(s[i], radix)) >= 0); + if (sign < 0) + big_complement(integer_part); + x = big_register_normalize(integer_part); + *ep = i; + return(x); +} + +static +@(defun left_parenthesis_reader (in c) + cl_object x, y; + cl_object *p; +@ + y = Cnil; + for (p = &y ; ; p = &(CDR(*p))) { + delimiting_char = code_char(')'); + in_list_flag = TRUE; + x = read_object(in); + if (x == OBJNULL) + break; + if (dot_flag) { + if (p == &y) + FEerror("A dot appeared after a left parenthesis.", 0); + in_list_flag = TRUE; + *p = read_object(in); + if (dot_flag) + FEerror("Two dots appeared consecutively.", 0); + c = read_char(in); + while (cat(c) == cat_whitespace) + c = read_char(in); + if (char_code(c) != ')') + FEerror("A dot appeared before a right parenthesis.", 0); + break; + } + *p = CONS(x, Cnil); + } + @(return y) +@) + /* + read_string(delim, in) reads + a simple string terminated by character code delim + and places it in token. + Delim is not included in the string but discarded. +*/ +static void +read_string(int delim, cl_object in) +{ + cl_index i; + cl_object c; + + i = 0; + for (;;) { + c = read_char(in); + if (char_code(c) == delim) + break; + else if (cat(c) == cat_single_escape) + c = read_char(in); + if (i >= cl_token->string.dim) + too_long_string(); + token_buffer[i++] = char_code(c); + } + cl_token->string.fillp = i; + cl_token->string.self[i] = '\0'; +} + +/* + Read_constituent(in) reads + a sequence of constituent characters from stream in + and places it in token_buffer. +*/ +static void +read_constituent(cl_object in) +{ + size_t i; + cl_object c; + + i = 0; + for (;;) { + c = read_char(in); + if (cat(c) != cat_constituent) { + unread_char(c, in); + break; + } + token_buffer[i++] = char_code(c); + } + cl_token->string.fillp = i; +} + +static +@(defun double_quote_reader (in c) +@ + read_string('"', in); + @(return copy_simple_string(cl_token)) +@) + +static +@(defun dispatch_reader (in dc) + cl_object c, x, y; + int i, d; +@ + if (READtable->readtable.table[char_code(dc)].dispatch_table == NULL) + FEerror("~C is not a dispatching macro character", 1, dc); + + c = read_char(in); + d = digitp((int)char_code(c), 10); + if (d >= 0) { + i = 0; + do { + i = 10*i + d; + c = read_char(in); + d = digitp(char_code(c), 10); + } while (d >= 0); + y = MAKE_FIXNUM(i); + } else + y = Cnil; + + x = READtable->readtable.table[char_code(dc)].dispatch_table[char_code(c)]; + return funcall(4, x, in, c, y); +@) + +static +@(defun single_quote_reader (in c) +@ + @(return CONS(Squote, CONS(read_object(in), Cnil))) +@) + +static +@(defun void_reader (in c) +@ + /* no result */ + @(return) +@) + +#define Lright_parenthesis_reader Lvoid_reader + +/* +int +Lcomma_reader(){} in backq.c +*/ + +static +@(defun semicolon_reader (in c) +@ + do + c = read_char(in); + while (char_code(c) != '\n'); + /* no result */ + @(return) +@) + +/* +int +Lbackquote_reader(){} +*/ + +/* + sharpmacro routines +*/ + +static +@(defun sharp_C_reader (in c d) + cl_object x, real, imag; +@ + if (d != Cnil && !READsuppress) + extra_argument('C', d); + c = read_char(in); + if (char_code(c) != '(') + FEerror("A left parenthesis is expected.", 0); + delimiting_char = code_char(')'); + real = read_object(in); + if (real == OBJNULL) + FEerror("No real part.", 0); + delimiting_char = code_char(')'); + imag = read_object(in); + if (imag == OBJNULL) + FEerror("No imaginary part.", 0); + delimiting_char = code_char(')'); + x = read_object(in); + if (x != OBJNULL) + FEerror("A right parenthesis is expected.", 0); + if (READsuppress) + @(return Cnil) + if (contains_sharp_comma(real) || + contains_sharp_comma(imag)) { + x = alloc_object(t_complex); + x->complex.real = real; + x->complex.imag = imag; + } else { + /* INV: make_complex() checks its types */ + x = make_complex(real, imag); + } + @(return x) +@) + +static +@(defun sharp_backslash_reader (in c d) +@ + if (d != Cnil && !READsuppress) + if (!FIXNUMP(d) || + fix(d) != 0) + FEerror("~S is an illegal CHAR-FONT.", 1, d); + /* assuming that CHAR-FONT-LIMIT is 1 */ + unread_char(code_char('\\'), in); + if (READsuppress) { + (void)read_object(in); + @(return Cnil) + } + READsuppress = TRUE; + (void)read_object(in); + READsuppress = FALSE; + c = cl_token; + if (c->string.fillp == 1) + c = code_char(c->string.self[0]); + else if (string_equal(c, STreturn)) + c = code_char('\r'); + else if (string_equal(c, STspace)) + c = code_char(' '); + else if (string_equal(c, STrubout)) + c = code_char('\177'); + else if (string_equal(c, STpage)) + c = code_char('\f'); + else if (string_equal(c, STtab)) + c = code_char('\t'); + else if (string_equal(c, STbackspace)) + c = code_char('\b'); + else if (string_equal(c, STlinefeed) || string_equal(c, STnewline)) + c = code_char('\n'); + else if (string_equal(c, STnull)) + c = code_char('\000'); + /* #\^x */ + else if (c->string.fillp == 2 && c->string.self[0] == '^') + c = code_char(c->string.self[1] & 037); + else if (c->string.self[0] =='\\' && c->string.fillp > 1) { + cl_index i, n; + for (n = 0, i = 1; i < c->string.fillp; i++) + if (c->string.self[i] < '0' || + '7' < c->string.self[i]) + FEerror("Octal digit expected.", 0); + else + n = 8*n + c->string.self[i] - '0'; + c = code_char(n & 0377); + } else + FEerror("~S is an illegal character name.", 1, c); + @(return c) +@) + +static +@(defun sharp_single_quote_reader (in c d) +@ + if(d != Cnil && !READsuppress) + extra_argument('#', d); + @(return CONS(Sfunction, CONS(read_object(in), Cnil))) +@) + +#define QUOTE 1 +#define EVAL 2 +#define LIST 3 +#define LISTA 4 +#define APPEND 5 +#define NCONC 6 + + +/* + *---------------------------------------------------------------------- + * Stack of unknown size + *---------------------------------------------------------------------- + */ + +#define INCREMENT 64 +#define ESTACK(st) volatile int _esize = 0; cl_object *(st), *(st ## 0); +#define ETOP(st) (st ## 0) + +#define EPUSH(st, val, count) \ + { int i; if (count == _esize) { \ + st = (cl_object *)alloca(INCREMENT*sizeof(cl_object)); \ + for ( i = 0; i < _esize; i++) \ + st[i] = st ## 0[i]; \ + (st ## 0) = st; st += _esize;\ + _esize += INCREMENT; \ + }; *(st)++ = (val);} + + +static +@(defun sharp_left_parenthesis_reader (in c d) + int dim, dimcount, i, a; + cl_object x, last; + ESTACK(vsp); +@ + if (Null(d) || READsuppress) + dim = -1; + else if (FIXNUMP(d)) + dim = fix(d); + if (backq_level > 0) { + unreadc_stream('(', in); + x = read_object(in); + a = backq_car(&x); + if (a == APPEND || a == NCONC) + FEerror(",at or ,. has appeared in an illegal position.", 0); + if (a == QUOTE) { + for (dimcount = 0; !endp(x); x = CDR(x), dimcount++) + EPUSH(vsp, CAR(x), dimcount); + goto L; + } + @(return list(4, siScomma, Sapply, + CONS(Squote, CONS(Svector, Cnil)), x)) + } + for (dimcount = 0 ;; dimcount++) { + delimiting_char = code_char(')'); + x = read_object(in); + if (x == OBJNULL) + break; + EPUSH(vsp, x, dimcount); + } +L: + if (dim >= 0) { + if (dimcount > dim) + FEerror("Too many elements in #(...).", 0); + if (dimcount == 0) + FEerror("Cannot fill the vector #().", 0); + else last = vsp[-1]; + } else + dim = dimcount; + x = alloc_simple_vector(dim, aet_object); + x->vector.self.t = alloc_align(dim * sizeof(cl_object), sizeof(cl_object)); + for (i = 0; i < dim; i++) + x->vector.self.t[i] = (i < dimcount) ? ETOP(vsp)[i] : last; + @(return x) +@) + +static +@(defun sharp_asterisk_reader (in c d) + int dim, dimcount, i; + cl_object x, last, elt; + ESTACK(vsp); +@ + if (READsuppress) { + read_constituent(in); + @(return Cnil) + } + if (Null(d)) + dim = -1; + else if (FIXNUMP(d)) + dim = fix(d); + for (dimcount = 0 ;; dimcount++) { + if (stream_at_end(in)) + break; + x = read_char(in); + if (char_code(x) != '0' && char_code(x) != '1') { + unread_char(x, in); + break; + } + EPUSH(vsp, x, dimcount); + } + if (dim >= 0) { + if (dimcount > dim) + FEerror("Too many elements in #*....", 0); + if (dimcount == 0) + FEerror("Cannot fill the bit-vector #*.", 0); + else last = vsp[-1]; + } else { + dim = dimcount; /* Beppe ? */ + last = MAKE_FIXNUM(0); + } + x = alloc_simple_bitvector(dim); + x->vector.self.bit = alloc_atomic((dim + CHAR_BIT - 1)/CHAR_BIT); + for (i = 0; i < dim; i++) { + elt = (i < dimcount) ? ETOP(vsp)[i] : last; + if (char_code(elt) == '0') + x->vector.self.bit[i/CHAR_BIT] &= ~(0200 >> i%CHAR_BIT); + else + x->vector.self.bit[i/CHAR_BIT] |= 0200 >> i%CHAR_BIT; + } + @(return x) +@) + +static +@(defun sharp_colon_reader (in c d) + cl_index length; + enum chattrib a; +@ + if (d != Cnil && !READsuppress) + extra_argument(':', d); + c = read_char(in); + a = cat(c); + escape_flag = FALSE; + length = 0; + goto L; + for (;;) { + if (length >= cl_token->string.dim) + too_long_token(); + token_buffer[length++] = char_code(c); + K: + if (stream_at_end(in)) + goto M; + c = read_char(in); + a = cat(c); + L: + if (a == cat_single_escape) { + c = read_char(in); + a = cat_constituent; + escape_flag = TRUE; + } else if (a == cat_multiple_escape) { + escape_flag = TRUE; + for (;;) { + if (stream_at_end(in)) + FEend_of_file(in); + c = read_char(in); + a = cat(c); + if (a == cat_single_escape) { + c = read_char(in); + a = cat_constituent; + } else if (a == cat_multiple_escape) + break; + if (length >= cl_token->string.dim) + too_long_token(); + token_buffer[length++] = char_code(c); + } + goto K; + } else if ('a' <= char_code(c) && char_code(c) <= 'z') + c = code_char(toupper(char_code(c))); + if (a == cat_whitespace || a == cat_terminating) + break; + } + if (preserving_whitespace_flag || cat(c) != cat_whitespace) + unread_char(c, in); + +M: + if (READsuppress) + @(return Cnil) + cl_token->string.fillp = length; + @(return make_symbol(copy_simple_string(cl_token))) +@) + +static +@(defun sharp_dot_reader (in c d) + cl_object lex_old = lex_env; +@ + if(d != Cnil && !READsuppress) + extra_argument('.', d); + if (READsuppress) + @(return Cnil) + in = read_object(in); + lex_new(); + in = eval(in, NULL); + lex_env = lex_old; + @(return in) +@) + +static +@(defun sharp_comma_reader (in c d) + cl_object lex_old = lex_env; +@ + if(d != Cnil && !READsuppress) + extra_argument(',', d); + if (READsuppress) + @(return Cnil) + in = read_object(in); + lex_new(); + in = eval(in, NULL); + lex_env = lex_old; + @(return in) +@) + +@(defun si::sharp_comma_reader_for_compiler (in c d) +@ + if(d != Cnil && !READsuppress) + extra_argument(',', d); + if (READsuppress) + @(return Cnil) + @(return CONS(siSsharp_comma, read_object(in))) +@) + +/* + For fasload. +*/ +static cl_object read_VV_block = OBJNULL; + +static +@(defun sharp_exclamation_reader (in c d) + cl_fixnum code; +@ + if(d != Cnil && !READsuppress) + extra_argument('!', d); + if (READsuppress) + @(return Cnil) + code = fixint(read_object(in)); + switch (code) { + case 0: { + cl_object name = read_object(in); + siLselect_package(1,name); + break; + } + case 1: { + cl_object name = read_object(in); + cl_object p = find_package(name); + if (Null(p)) make_package(name,Cnil,Cnil); + break; + } + default: + code = -code - 1; + if (code < 0 || code >= read_VV_block->cblock.data_size) + FEerror("Bogus binary file. #!~S unknown.",1, + MAKE_FIXNUM(code)); + @(return read_VV_block->cblock.data[code]) + } + @(return) +@) + +static +@(defun sharp_B_reader (in c d) + cl_index i; + cl_object x; +@ + if(d != Cnil && !READsuppress) + extra_argument('B', d); + read_constituent(in); + if (READsuppress) + @(return Cnil) + x = parse_number(token_buffer, cl_token->string.fillp, &i, 2); + if (x == OBJNULL || i != cl_token->string.fillp) + FEerror("Cannot parse the #B readmacro.", 0); + if (type_of(x) == t_shortfloat || + type_of(x) == t_longfloat) + FEerror("The float ~S appeared after the #B readmacro.", + 1, x); + @(return x) +@) + +static +@(defun sharp_O_reader (in c d) + cl_index i; + cl_object x; +@ + if(d != Cnil && !READsuppress) + extra_argument('O', d); + read_constituent(in); + if (READsuppress) + @(return Cnil) + x = parse_number(token_buffer, cl_token->string.fillp, &i, 8); + if (x == OBJNULL || i != cl_token->string.fillp) + FEerror("Cannot parse the #O readmacro.", 0); + if (type_of(x) == t_shortfloat || + type_of(x) == t_longfloat) + FEerror("The float ~S appeared after the #O readmacro.", + 1, x); + @(return x) +@) + +static +@(defun sharp_X_reader (in c d) + cl_index i; + cl_object x; +@ + if(d != Cnil && !READsuppress) + extra_argument('X', d); + read_constituent(in); + if (READsuppress) + @(return Cnil) + x = parse_number(token_buffer, cl_token->string.fillp, &i, 16); + if (x == OBJNULL || i != cl_token->string.fillp) + FEerror("Cannot parse the #X readmacro.", 0); + if (type_of(x) == t_shortfloat || + type_of(x) == t_longfloat) + FEerror("The float ~S appeared after the #X readmacro.", + 1, x); + @(return x) +@) + +static +@(defun sharp_R_reader (in c d) + int radix; + cl_index i; + cl_object x; +@ + if (READsuppress) + radix = 10; + else if (FIXNUMP(d)) { + radix = fix(d); + if (radix > 36 || radix < 2) + FEerror("~S is an illegal radix.", 1, d); + } else + FEerror("No radix was supplied in the #R readmacro.", 0); + read_constituent(in); + if (READsuppress) + @(return Cnil) + x = parse_number(token_buffer, cl_token->string.fillp, &i, radix); + if (x == OBJNULL || i != cl_token->string.fillp) + FEerror("Cannot parse the #R readmacro.", 0); + if (type_of(x) == t_shortfloat || + type_of(x) == t_longfloat) + FEerror("The float ~S appeared after the #R readmacro.", + 1, x); + @(return x) +@) + +#define sharp_A_reader Lvoid_reader +#define sharp_S_reader Lvoid_reader + +static +@(defun sharp_eq_reader (in c d) + cl_object pair, value; +@ + if (READsuppress) @(return) + if (Null(d)) + FEerror("The #= readmacro requires an argument.", 0); + if (assql(d, sharp_eq_context) != Cnil) + FEerror("Duplicate definitions for #~D=.", 1, d); + pair = CONS(d, Cnil); + sharp_eq_context = CONS(pair, sharp_eq_context); + value = read_object(in); + if (value == pair) + FEerror("#~D# is defined by itself.", 1, d); + @(return (CDR(pair) = value)) +@) + +static +@(defun sharp_sharp_reader (in c d) + cl_object pair; +@ + if (READsuppress) @(return) + if (Null(d)) + FEerror("The ## readmacro requires an argument.", 0); + pair = assq(d, sharp_eq_context); + if (pair != Cnil) + @(return pair) + FEerror("#~D# is undefined.", 1, d); +@) + +static cl_object +do_patch_sharp(cl_object x) +{ + cs_check(x); + + switch (type_of(x)) { + case t_cons: { + cl_object y = x; + cl_object *place = &x; + do { + /* This was the result of a #d# */ + if (CAR(y) == OBJNULL) { + *place = CDR(y); + return x; + } else + CAR(y) = do_patch_sharp(CAR(y)); + place = &CDR(y); + y = CDR(y); + } while (CONSP(y)); + break; + } + case t_vector: { + cl_index i; + + for (i = 0; i < x->vector.fillp; i++) + x->vector.self.t[i] = do_patch_sharp(x->vector.self.t[i]); + break; + } + case t_array: { + cl_index i, j; + + for (i = 0, j = 1; i < x->array.rank; i++) + j *= x->array.dims[i]; + for (i = 0; i < j; i++) + x->array.self.t[i] = do_patch_sharp(x->array.self.t[i]); + break; + } + default: + } + return(x); +} + +static cl_object +patch_sharp(cl_object x) +{ + cl_object pair = sharp_eq_context; + loop_for_in(pair) { + CAAR(pair) = OBJNULL; + } end_loop_for_in; + + x = do_patch_sharp(x); + + pair = sharp_eq_context; + loop_for_in(pair) { + CAAR(pair) = Cnil; + } end_loop_for_in; + return x; +} + +#define Lsharp_plus_reader Lvoid_reader +#define Lsharp_minus_reader Lvoid_reader +#define Lsharp_less_than_reader Lvoid_reader +#define Lsharp_whitespace_reader Lvoid_reader +#define Lsharp_right_parenthesis_reader Lvoid_reader + +static +@(defun sharp_vertical_bar_reader (in ch d) + int c; + int level = 0; +@ + if (d != Cnil && !READsuppress) + extra_argument('|', d); + for (;;) { + c = char_code(read_char(in)); + L: + if (c == '#') { + c = char_code(read_char(in)); + if (c == '|') + level++; + } else if (c == '|') { + c = char_code(read_char(in)); + if (c == '#') { + if (level == 0) + break; + else + --level; + } else + goto L; + } + } + @(return) + /* no result */ +@) + +static +@(defun default_dispatch_macro (in c d) +@ + FEerror("Undefined dispatch macro character.", 1, c); +@) + +/* + #P" ... " returns the pathname with namestring ... . +*/ +static +@(defun sharp_P_reader (in c d) +@ + @(return coerce_to_pathname(read_object(in))) +@) + +/* + #" ... " returns the pathname with namestring ... . +*/ +static +@(defun sharp_double_quote_reader (in c d) +@ + if (d != Cnil && !READsuppress) + extra_argument('"', d); + unread_char(c, in); + @(return coerce_to_pathname(read_object(in))) +@) + +/* + #$ fixnum returns a random-state with the fixnum + as its content. +*/ +static +@(defun sharp_dollar_reader (in c d) + cl_object output; +@ + if (d != Cnil && !READsuppress) + extra_argument('$', d); + c = read_object(in); + if (!FIXNUMP(c)) + FEerror("Cannot make a random-state with the value ~S.", + 1, c); + output = alloc_object(t_random); + output->random.value = fix(c); + @(return output) +@) + +/* + readtable routines +*/ + +cl_object +copy_readtable(cl_object from, cl_object to) +{ + struct readtable_entry *rtab; + cl_index i; + + if (Null(to)) { + to = alloc_object(t_readtable); + to->readtable.table = NULL; + /* Saving for GC. */ + to->readtable.table + = rtab + = alloc_align(RTABSIZE * sizeof(struct readtable_entry), sizeof(struct readtable_entry)); + memcpy(rtab, from->readtable.table, + RTABSIZE * sizeof(struct readtable_entry)); +/* + for (i = 0; i < RTABSIZE; i++) + rtab[i] = from->readtable.table[i]; +*/ + /* structure assignment */ + } else + rtab=to->readtable.table; + for (i = 0; i < RTABSIZE; i++) + if (from->readtable.table[i].dispatch_table != NULL) { + rtab[i].dispatch_table + = alloc_align(RTABSIZE * sizeof(cl_object), sizeof(cl_object)); + memcpy(rtab[i].dispatch_table, from->readtable.table[i].dispatch_table, + RTABSIZE * sizeof(cl_object *)); +/* + for (j = 0; j < RTABSIZE; j++) + rtab[i].dispatch_table[j] + = from->readtable.table[i].dispatch_table[j]; +*/ + } + return(to); +} + +cl_object +current_readtable(void) +{ + cl_object r; + + r = symbol_value(Vreadtable); + if (type_of(r) != t_readtable) { + SYM_VAL(Vreadtable) = copy_readtable(standard_readtable, Cnil); + FEerror("The value of *READTABLE*, ~S, was not a readtable.", + 1, r); + } + return(r); +} + + +@(defun read (&optional (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep + &aux x) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + read_ch_fun = readc; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + read_ch_fun = interactive_readc; + else +#endif CLOS + FEwrong_type_argument(Sstream, strm); + if (Null(recursivep)) + preserving_whitespace_flag = FALSE; + detect_eos_flag = TRUE; + if (Null(recursivep)) + x = read_object_non_recursive(strm); + else + x = read_object_recursive(strm); + if (x == OBJNULL) { + if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value) + FEend_of_file(strm); + } + @(return x) +@) + +@(defun read_preserving_whitespace + (&optional (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep + &aux x) + cl_object c; +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else + read_ch_fun = readc; + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + read_ch_fun = interactive_readc; + else +#endif CLOS + FEwrong_type_argument(Sstream, strm); + while (!stream_at_end(strm)) { + c = read_char(strm); + if (cat(c) != cat_whitespace) { + unread_char(c, strm); + goto READ; + } + } + if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value) + FEend_of_file(strm); + +READ: + if (Null(recursivep)) + preserving_whitespace_flag = TRUE; + if (Null(recursivep)) + x = read_object_non_recursive(strm); + else + x = read_object_recursive(strm); + @(return x) +@) + +@(defun read_delimited_list + (d + &optional (strm symbol_value(Vstandard_input)) + recursivep + &aux l x) + + cl_object *p; + bool e; + volatile cl_object old_sharp_eq_context; + volatile int old_backq_level; + +@ + if (!CHARACTERP(d)) + FEtype_error_character(d); + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + assert_type_stream(strm); + if (Null(recursivep)) { + old_sharp_eq_context = sharp_eq_context; + old_backq_level = backq_level; + setup_READ(); + sharp_eq_context = Cnil; + backq_level = 0; + if (frs_push(FRS_PROTECT, Cnil)) { + e = TRUE; + goto L; + } + } + l = Cnil; + p = &l; + preserving_whitespace_flag = FALSE; /* necessary? */ + for (;;) { + delimiting_char = d; + x = read_object_recursive(strm); + if (x == OBJNULL) + break; + *p = CONS(x, Cnil); + p = &(CDR((*p))); + } + if (Null(recursivep)) { + if (!Null(sharp_eq_context)) + l = patch_sharp(l); + e = FALSE; + L: + frs_pop(); + sharp_eq_context = old_sharp_eq_context; + backq_level = old_backq_level; + if (e) unwind(nlj_fr, nlj_tag); + } + @(return l) +@) + +@(defun read_line (&optional (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep + &aux c) + cl_index i; +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + if (stream_at_end(strm)) { + if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value Ct) + else + FEend_of_file(strm); + } + i = 0; + for (;;) { + c = read_char(strm); + if (char_code(c) == '\n') { + c = Cnil; + break; + } + if (i >= cl_token->string.dim) + too_long_string(); + cl_token->string.self[i++] = char_code(c); + if (stream_at_end(strm)) { + c = Ct; + break; + } + } +#ifdef CRLF + if (i > 0 && cl_token->string.self[i-1] == '\r') i--; +#endif CRLF + cl_token->string.fillp = i; + @(return copy_simple_string(cl_token) c) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(2, Sstream_read_line, strm); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun read_char (&optional (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + if (stream_at_end(strm)) { + if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value) + else + FEend_of_file(strm); + } + @(return read_char(strm)) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(2, Sstream_read_char, strm); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun unread_char (c &optional (strm symbol_value(Vstandard_input))) +@ + /* INV: unread_char() checks the type `c' */ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + unread_char(c, strm); + @(return Cnil) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(3, Sstream_unread_char, strm, c); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun peek_char (&optional peek_type + (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep) + cl_object c; +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + setup_READtable(); + if (Null(peek_type)) { + if (stream_at_end(strm)) { + if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value) + else + FEend_of_file(strm); + } + c = read_char(strm); + unread_char(c, strm); + @(return c) + } + if (peek_type == Ct) { + while (!stream_at_end(strm)) { + c = read_char(strm); + if (cat(c) != cat_whitespace) { + unread_char(c, strm); + @(return c) + } + } + if (Null(eof_errorp)) + @(return eof_value) + else + FEend_of_file(strm); + } + /* INV: char_eq() checks the type of `peek_type' */ + while (!stream_at_end(strm)) { + c = read_char(strm); + if (char_eq(c, peek_type)) { + unread_char(c, strm); + @(return c) + } + } + if (Null(eof_errorp)) + @(return eof_value) + else + FEend_of_file(strm); + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(3, Sstream_peek_char, strm, peek_type); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun listen (&optional (strm symbol_value(Vstandard_input))) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + if (listen_stream(strm)) + @(return Ct) + else + @(return Cnil) + } + } + else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(2, Sstream_listen, strm); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun read_char_no_hang (&optional (strm symbol_value(Vstandard_input)) + (eof_errorp Ct) + eof_value + recursivep) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); + assert_type_stream(strm); +#if 0 + if (!listen_stream(strm)) + /* Incomplete! */ + @(return Cnil) + @(return read_char(strm)) +#else + /* + This implementation fails for EOF and handles + CLOS streams. + */ +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } else { + if (listen_stream(strm)) + @(return read_char(strm)) + else if (!stream_at_end(strm)) + @(return Cnil) + else if (Null(eof_errorp) && Null(recursivep)) + @(return eof_value) + else + FEend_of_file(strm); + } + } + else +#ifdef CLOS + /* FIXME! Is this all right? */ + if (type_of(strm) == t_instance) { + if (_funcall(2, Sstream_listen, strm) == Cnil) + @(return Cnil) + else + return funcall(2, Sstream_read_char, strm); + } else +#endif + FEerror("~S is not a stream.", 1, strm); +#endif +@) + +@(defun clear_input (&optional (strm symbol_value(Vstandard_input))) +@ + if (Null(strm)) + strm = symbol_value(Vstandard_input); + else if (strm == Ct) + strm = symbol_value(Vterminal_io); +RETRY: if (type_of(strm) == t_stream) { + if (strm->stream.mode == (short)smm_synonym) { + strm = symbol_value(strm->stream.object0); + goto RETRY; + } + else { + clear_input_stream(strm); + @(return Cnil) + } + } else +#ifdef CLOS + if (type_of(strm) == t_instance) + return funcall(2, Sstream_clear_input, strm); + else +#endif + FEerror("~S is not a stream.", 1, strm); +@) + +@(defun parse_integer (strng + &key (start MAKE_FIXNUM(0)) + end + (radix MAKE_FIXNUM(10)) + junk_allowed + &aux x) + cl_index s, e, ep; +@ + assert_type_string(strng); + get_string_start_end(strng, start, end, &s, &e); + if (!FIXNUMP(radix) || + fix(radix) < 2 || fix(radix) > 36) + FEerror("~S is an illegal radix.", 1, radix); + setup_READtable(); + while (READtable->readtable.table[strng->string.self[s]].syntax_type + == cat_whitespace && s < e) + s++; + if (s >= e) { + if (junk_allowed != Cnil) + @(return Cnil MAKE_FIXNUM(s)) + else + goto CANNOT_PARSE; + } + x = parse_integer(strng->string.self+s, e-s, &ep, fix(radix)); + if (x == OBJNULL) { + if (junk_allowed != Cnil) + @(return Cnil MAKE_FIXNUM(ep+s)) + else + goto CANNOT_PARSE; + } + if (junk_allowed != Cnil) + @(return x MAKE_FIXNUM(ep+s)) + for (s += ep ; s < e; s++) + if (READtable->readtable.table[strng->string.self[s]].syntax_type + != cat_whitespace) + goto CANNOT_PARSE; + @(return x MAKE_FIXNUM(e)) + +CANNOT_PARSE: + FEerror("Cannot parse an integer in the string ~S.", 1, strng); +@) + +@(defun read_byte (binary_input_stream + &optional eof_errorp eof_value) + int c; +@ + assert_type_stream(binary_input_stream); + if (stream_at_end(binary_input_stream)) { + if (Null(eof_errorp)) + @(return eof_value) + else + FEend_of_file(binary_input_stream); + } + c = readc_stream(binary_input_stream); + @(return MAKE_FIXNUM(c)) +@) + +@(defun read_bytes (stream string start end) + int is, ie, c; FILE *fp; +@ + assert_type_stream(stream); + if (stream->stream.mode == smm_closed) + closed_stream(stream); + + /* FIXME! this may fail! */ + is = fix(start); + ie = fix(end); + fp = stream->stream.file; + if (fp == NULL) fp = stream->stream.object0->stream.file; + c = fread (string->string.self + is, sizeof(unsigned char), + ie - is, + fp); + @(return MAKE_FIXNUM(c)) +@) + + + +@(defun copy_readtable (&o (from current_readtable()) to) +@ + if (Null(from)) { + from = standard_readtable; + if (to != Cnil) + assert_type_readtable(to); + to = copy_readtable(from, to); + to->readtable.table['#'].dispatch_table['!'] + = default_dispatch_macro; + /* We must forget #! macro. */ + @(return to) + } + assert_type_readtable(from); + if (to != Cnil) + assert_type_readtable(to); + @(return copy_readtable(from, to)) +@) + +@(defun readtablep (readtable) +@ + @(return ((type_of(readtable) == t_readtable)? Ct : Cnil)) +@) + +static struct readtable_entry* +read_table_entry(cl_object rdtbl, cl_object c) +{ + /* INV: char_code() checks the type of `c' */ + assert_type_readtable(rdtbl); + return &(rdtbl->readtable.table[char_code(c)]); +} + +@(defun set_syntax_from_char (tochr fromchr + &o (tordtbl current_readtable()) + fromrdtbl) + struct readtable_entry*torte, *fromrte; +@ + /* INV: read_table_entry() checks all values */ + if (Null(fromrdtbl)) + fromrdtbl = standard_readtable; + /* INV: char_code() checks the types of `tochar',`fromchar' */ + torte = read_table_entry(tordtbl, tochr); + fromrte = read_table_entry(fromrdtbl, fromchr); + torte->syntax_type = fromrte->syntax_type; + torte->macro = fromrte->macro; + if ((torte->dispatch_table = fromrte->dispatch_table) != NULL) { + size_t rtab_size = RTABSIZE * sizeof(cl_object); + torte->dispatch_table = alloc(rtab_size); + memcpy(torte->dispatch_table, fromrte->dispatch_table, rtab_size); + } + @(return Ct) +@) + +@(defun set_macro_character (chr fnc + &optional ntp + (rdtbl current_readtable())) + struct readtable_entry*entry; +@ + /* INV: read_table_entry() checks our arguments */ + entry = read_table_entry(rdtbl, chr); + if (ntp != Cnil) + entry->syntax_type = cat_non_terminating; + else + entry->syntax_type = cat_terminating; + entry->macro = fnc; + @(return Ct) +@) + +@(defun get_macro_character (chr &o (rdtbl current_readtable())) + struct readtable_entry*entry; + cl_object m; +@ + + /* fix to allow NIL as readtable argument. Beppe */ + if (Null(rdtbl)) + rdtbl = standard_readtable; + /* INV: read_table_entry() checks our arguments */ + entry = read_table_entry(rdtbl, chr); + m = entry->macro; + if (m == OBJNULL) + @(return Cnil) + if (entry->syntax_type = cat_non_terminating) + @(return m Ct) + else + @(return m Cnil) +@) + +@(defun make_dispatch_macro_character (chr + &optional ntp (rdtbl current_readtable())) + struct readtable_entry*entry; + cl_object *table; + int i; +@ + /* INV: read_table_entry() checks our arguments */ + entry = read_table_entry(rdtbl, chr); + if (ntp != Cnil) + entry->syntax_type = cat_non_terminating; + else + entry->syntax_type = cat_terminating; + table = alloc(RTABSIZE * sizeof(cl_object)); + entry->dispatch_table = table; + for (i = 0; i < RTABSIZE; i++) + table[i] = default_dispatch_macro; + entry->macro = dispatch_reader; + @(return Ct) +@) + +@(defun set_dispatch_macro_character (dspchr subchr fnc + &optional (rdtbl current_readtable())) + struct readtable_entry*entry; + cl_fixnum subcode; +@ + entry = read_table_entry(rdtbl, dspchr); + if (entry->macro != dispatch_reader || entry->dispatch_table == NULL) + FEerror("~S is not a dispatch character.", 1, dspchr); + subcode = char_code(subchr); + if ('a' <= subcode && subcode <= 'z') + subcode = toupper(subcode); + entry->dispatch_table[subcode] = fnc; + @(return Ct) +@) + +@(defun get_dispatch_macro_character (dspchr subchr + &optional (rdtbl current_readtable())) + struct readtable_entry*entry; + cl_fixnum subcode; +@ + if (Null(rdtbl)) + rdtbl = standard_readtable; + entry = read_table_entry(rdtbl, dspchr); + if (entry->macro != dispatch_reader || entry->dispatch_table == NULL) + FEerror("~S is not a dispatch character.", 1, dspchr); + subcode = char_code(subchr); + if (digitp(subcode, 10) >= 0) + @(return Cnil) + @(return entry->dispatch_table[subcode]) +@) + +cl_object +string_to_object(cl_object x) +{ + cl_object in; + + in = make_string_input_stream(x, 0, x->string.fillp); + preserving_whitespace_flag = FALSE; + detect_eos_flag = FALSE; + x = read_object(in); + return(x); +} + +@(defun si::string_to_object (str) +@ + assert_type_string(str); + @(return string_to_object(str)) +@) + +@(defun si::standard_readtable () +@ + @(return standard_readtable) +@) + +static void +too_long_token(void) +{ + char *q; + + q = alloc_atomic(cl_token->string.dim*2); + memcpy(q, cl_token->string.self, cl_token->string.dim); + cl_token->string.self = q; + cl_token->string.dim *= 2; +} + +static void +too_long_string(void) +{ + char *q; + + q = alloc_atomic(cl_token->string.dim*2); + memcpy(q, cl_token->string.self, cl_token->string.dim); + cl_token->string.self = q; + cl_token->string.dim *= 2; +} + +static void +extra_argument(int c, cl_object d) +{ + FEerror("~S is an extra argument for the #~C readmacro.", + 2, d, code_char(c)); +} + + +#define make_cf(f) make_cfun((f), Cnil, NULL) + +void +init_read(void) +{ + struct readtable_entry *rtab; + cl_object *dtab; + int i; + + standard_readtable = alloc_object(t_readtable); + register_root(&standard_readtable); + + standard_readtable->readtable.table + = rtab + = alloc(RTABSIZE * sizeof(struct readtable_entry)); + for (i = 0; i < RTABSIZE; i++) { + rtab[i].syntax_type = cat_constituent; + rtab[i].macro = OBJNULL; + rtab[i].dispatch_table = NULL; + } + + dispatch_reader = make_cf(Ldispatch_reader); + register_root(&dispatch_reader); + + rtab['\t'].syntax_type = cat_whitespace; + rtab['\n'].syntax_type = cat_whitespace; + rtab['\f'].syntax_type = cat_whitespace; + rtab['\r'].syntax_type = cat_whitespace; + rtab[' '].syntax_type = cat_whitespace; + rtab['"'].syntax_type = cat_terminating; + rtab['"'].macro = make_cf(Ldouble_quote_reader); + rtab['#'].syntax_type = cat_non_terminating; + rtab['#'].macro = dispatch_reader; + rtab['\''].syntax_type = cat_terminating; + rtab['\''].macro = make_cf(Lsingle_quote_reader); + rtab['('].syntax_type = cat_terminating; + rtab['('].macro = make_cf(Lleft_parenthesis_reader); + rtab[')'].syntax_type = cat_terminating; + rtab[')'].macro = make_cf(Lright_parenthesis_reader); +/* + rtab[','].syntax_type = cat_terminating; + rtab[','].macro = make_cf(Lcomma_reader); +*/ + rtab[';'].syntax_type = cat_terminating; + rtab[';'].macro = make_cf(Lsemicolon_reader); + rtab['\\'].syntax_type = cat_single_escape; +/* + rtab['`'].syntax_type = cat_terminating; + rtab['`'].macro = make_cf(Lbackquote_reader); +*/ + rtab['|'].syntax_type = cat_multiple_escape; +/* + rtab['|'].macro = make_cf(Lvertical_bar_reader); +*/ + + default_dispatch_macro = make_cf(Ldefault_dispatch_macro); +#ifndef THREADS + register_root(&default_dispatch_macro); +#endif + + rtab['#'].dispatch_table + = dtab + = alloc(RTABSIZE * sizeof(cl_object)); + for (i = 0; i < RTABSIZE; i++) + dtab[i] = default_dispatch_macro; + dtab['C'] = dtab['c'] = make_cf(Lsharp_C_reader); + dtab['\\'] = make_cf(Lsharp_backslash_reader); + dtab['\''] = make_cf(Lsharp_single_quote_reader); + dtab['('] = make_cf(Lsharp_left_parenthesis_reader); + dtab['*'] = make_cf(Lsharp_asterisk_reader); + dtab[':'] = make_cf(Lsharp_colon_reader); + dtab['.'] = make_cf(Lsharp_dot_reader); + dtab['!'] = make_cf(Lsharp_exclamation_reader); + /* Used for fasload only. */ + dtab[','] = make_cf(Lsharp_comma_reader); + dtab['B'] = dtab['b'] = make_cf(Lsharp_B_reader); + dtab['O'] = dtab['o'] = make_cf(Lsharp_O_reader); + dtab['X'] = dtab['x'] = make_cf(Lsharp_X_reader); + dtab['R'] = dtab['r'] = make_cf(Lsharp_R_reader); +/* + dtab['A'] = dtab['a'] = make_cf(Lsharp_A_reader); + dtab['S'] = dtab['s'] = make_cf(Lsharp_S_reader); +*/ + dtab['A'] = dtab['a'] = make_si_ordinary("SHARP-A-READER"); + dtab['S'] = dtab['s'] = make_si_ordinary("SHARP-S-READER"); + dtab['P'] = dtab['p'] = make_cf(Lsharp_P_reader); + + dtab['='] = make_cf(Lsharp_eq_reader); + dtab['#'] = make_cf(Lsharp_sharp_reader); + dtab['+'] = make_cf(Lsharp_plus_reader); + dtab['-'] = make_cf(Lsharp_minus_reader); +/* + dtab['<'] = make_cf(Lsharp_less_than_reader); +*/ + dtab['|'] = make_cf(Lsharp_vertical_bar_reader); + dtab['"'] = make_cf(Lsharp_double_quote_reader); + /* This is specific to this implementation */ + dtab['$'] = make_cf(Lsharp_dollar_reader); + /* This is specific to this implimentation */ +/* + dtab[' '] = dtab['\t'] = dtab['\n'] = dtab['\f'] + = make_cf(Lsharp_whitespace_reader); + dtab[')'] = make_cf(Lsharp_right_parenthesis_reader); +*/ + + init_backq(); + + SYM_VAL(Vreadtable) = + copy_readtable(standard_readtable, Cnil); + SYM_VAL(Vreadtable)->readtable.table['#'].dispatch_table['!'] + = default_dispatch_macro; /* We must forget #! macro. */ + SYM_VAL(Vread_default_float_format) + = Ssingle_float; + SYM_VAL(Vread_base) = MAKE_FIXNUM(10); + SYM_VAL(Vread_suppress) = Cnil; + + READtable = symbol_value(Vreadtable); + register_root(&READtable); + READdefault_float_format = 'S'; + READbase = 10; + READsuppress = FALSE; + + sharp_eq_context = Cnil; + + delimiting_char = OBJNULL; + register_root(&delimiting_char); + + detect_eos_flag = FALSE; + in_list_flag = FALSE; + dot_flag = FALSE; + + read_ch_fun = readc; +} + +/* + *---------------------------------------------------------------------- + * + * read_VV -- + * reads the data vector from stream into vector VV + * + * Results: + * a vector. + * + *---------------------------------------------------------------------- + */ +void +read_VV(cl_object block, void *entry) +{ + typedef void (*entry_point_ptr)(cl_object); + volatile cl_object x, v; + int i; + bool e; + cl_object in; + cl_object old_READtable; + int old_READdefault_float_format; + int old_READbase; + int old_READsuppress; + int old_backq_level; + cl_object old_sharp_eq_context; + cl_object old_package; + + entry_point_ptr entry_point = entry; + cl_object *VV; + int len; +#ifdef PDE + bds_ptr old_bds_top = bds_top; +#endif + + if (block == NULL) + block = alloc_object(t_codeblock); + + (*entry_point)(block); + VV = block->cblock.data; + len = block->cblock.data_size; + + old_READtable = READtable; + old_READdefault_float_format = READdefault_float_format; + old_READbase = READbase; + old_READsuppress = READsuppress; + old_sharp_eq_context = sharp_eq_context; + old_backq_level = backq_level; + + old_package = SYM_VAL(Vpackage); + SYM_VAL(Vpackage) = lisp_package; + + setup_standard_READ(); + + in = make_string_input_stream(make_simple_string(block->cblock.data_text), + 0, block->cblock.data_text_size); + if (frs_push(FRS_PROTECT, Cnil)) + e = TRUE; + else { + read_VV_block = block; + for (i = 0 ; i < len; i++) { + sharp_eq_context = Cnil; + backq_level = 0; + preserving_whitespace_flag = FALSE; + detect_eos_flag = FALSE; + x = read_object(in); + if (x == OBJNULL) + break; + if (!Null(sharp_eq_context)) + x = patch_sharp(x); + VV[i] = x; + } + if (i < len) + FEerror("Not enough data while loading binary file",0); + SYM_VAL(Vpackage) = old_package; +#ifdef PDE + bds_bind(siVsource_pathname, VV[block->cblock.source_pathname]); +#endif + (*entry_point)(MAKE_FIXNUM(0)); + e = FALSE; + } + + frs_pop(); + close_stream(in, 0); + + read_VV_block = OBJNULL; +#ifdef PDE + bds_unwind(old_bds_top); +#endif + + READtable = old_READtable; + READdefault_float_format = old_READdefault_float_format; + READbase = old_READbase; + READsuppress = old_READsuppress; + sharp_eq_context = old_sharp_eq_context; + backq_level = old_backq_level; + if (e) unwind(nlj_fr, nlj_tag); +} + diff --git a/src/c/reference.d b/src/c/reference.d new file mode 100644 index 000000000..b2265c951 --- /dev/null +++ b/src/c/reference.d @@ -0,0 +1,148 @@ +/* + reference.c -- Reference in Constants and Variables. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +#define SBOUNDP(sym) (SYM_VAL(sym) == OBJNULL) +#define FBOUNDP(sym) (SYM_FUN(sym) == OBJNULL) + +@(defun fboundp (sym) + cl_object output; +@ + if (!SYMBOLP(sym)) { + cl_object sym1 = setf_namep(sym); + if (sym1 != OBJNULL) + sym = sym1; + else + FEtype_error_symbol(sym); + } + if (sym->symbol.isform) + output = Ct; + else if (FBOUNDP(sym)) + output = Cnil; + else + output = Ct; + @(return output) +@) + +cl_object +symbol_function(cl_object sym) +{ + if (!SYMBOLP(sym)) { + cl_object sym1 = setf_namep(sym); + if (sym1 != OBJNULL) + sym = sym1; + else + FEtype_error_symbol(sym); + } + if (sym->symbol.isform || sym->symbol.mflag) + FEinvalid_function(sym); + if (FBOUNDP(sym)) + FEundefined_function(sym); + return(SYM_FUN(sym)); +} + +/* + Symbol-function returns + function-closure for function + (macro . function-closure) for macros + (special . address) for special forms. + (if defined CLOS it returns also + generic-function for generic functions) +*/ +@(defun symbol_function (sym) + cl_object output; +@ + if (!SYMBOLP(sym)) { + cl_object sym1 = setf_namep(sym); + if (sym1 != OBJNULL) + sym = sym1; + else + FEtype_error_symbol(sym); + } + if (sym->symbol.isform) + output = Sspecial; + else if (FBOUNDP(sym)) + FEundefined_function(sym); + else if (sym->symbol.mflag) + output = CONS(Smacro, SYM_FUN(sym)); + else + output = SYM_FUN(sym); + @(return output) +@) + +@(defun si::coerce_to_function (fun) + enum cl_type t = type_of(fun); +@ + if (t == t_symbol) { + cl_object fd = lex_fun_sch(fun); + if (!Null(fd)) + return CADDR(fd); + else if (FBOUNDP(fun) || fun->symbol.mflag) + FEundefined_function(fun); + else + @(return SYM_FUN(fun)) + } else if (t == t_cons && CAR(fun) == Slambda) { + return siLmake_lambda(2, Cnil, CDR(fun)); + } else { + cl_object setf_sym = setf_namep(fun); + if ((setf_sym != OBJNULL) && !FBOUNDP(setf_sym)) + @(return SYM_FUN(setf_sym)) + else + FEinvalid_function(fun); + } +@) + +@(defun symbol_value (sym) +@ + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + if (SBOUNDP(sym)) + FEunbound_variable(sym); + @(return SYM_VAL(sym)) +@) + +@(defun boundp (sym) +@ + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + @(return (SBOUNDP(sym)? Cnil : Ct)) +@) + +@(defun macro_function (sym &optional env) + cl_object fd; +@ + if (!SYMBOLP(sym)) + FEtype_error_symbol(sym); + if (Null(env)) + fd = Cnil; + else { + fd = search_macro(sym, env); + if (!Null(fd)) @(return fd) + } + if (sym->symbol.mflag) + fd = SYM_FUN(sym); + @(return fd) +@) + +@(defun special_form_p (form) +@ + if (!SYMBOLP(form)) + FEtype_error_symbol(form); + @(return (form->symbol.isform? Ct : Cnil)) +@) diff --git a/src/c/sequence.d b/src/c/sequence.d new file mode 100644 index 000000000..23625a825 --- /dev/null +++ b/src/c/sequence.d @@ -0,0 +1,466 @@ +/* + sequence.d -- Sequence routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "ecls-inl.h" + +#undef endp + +#define endp(obje) (endp_temp = (obje), CONSP(endp_temp) ? \ + FALSE : endp_temp == Cnil ? TRUE : \ + (FEwrong_type_argument(Slist, endp_temp), FALSE)) + +/* + I know the following name is not good. +*/ +cl_object +alloc_simple_vector(int l, enum aelttype aet) +{ + cl_object x; + + x = alloc_object(t_vector); + x->vector.hasfillp = FALSE; + x->vector.adjustable = FALSE; + x->vector.displaced = Cnil; + x->vector.dim = x->vector.fillp = l; + x->vector.self.t = NULL; + x->vector.elttype = (short)aet; + return(x); +} + +cl_object +alloc_simple_bitvector(int l) +{ + cl_object x; + + x = alloc_object(t_bitvector); + x->vector.hasfillp = FALSE; + x->vector.adjustable = FALSE; + x->vector.displaced = Cnil; + x->vector.dim = x->vector.fillp = l; + x->vector.offset = 0; + x->vector.self.bit = NULL; + return(x); +} + +@(defun elt (x i) +@ + @(return elt(x, fixint(i))) +@) + +cl_object +elt(cl_object seq, cl_fixnum index) +{ + cl_fixnum i; + cl_object l; + cl_object endp_temp; + + if (index < 0) + goto E; + switch (type_of(seq)) { + case t_cons: + for (i = index, l = seq; i > 0; --i) + if (endp(l)) + goto E; + else + l = CDR(l); + if (endp(l)) + goto E; + return(CAR(l)); + + case t_vector: + case t_bitvector: + if (index >= seq->vector.fillp) + goto E; + return(aref(seq, index)); + + case t_string: + if (index >= seq->string.fillp) + goto E; + return(code_char(seq->string.self[index])); + + default: + FEerror("~S is not a sequence.", 1, seq); + } +E: + FEtype_error_index(MAKE_FIXNUM(index)); +} + +@(defun si::elt_set (seq index val) +@ + @(return elt_set(seq, fixint(index), val)) +@) + +cl_object +elt_set(cl_object seq, cl_fixnum index, cl_object val) +{ + int i; + cl_object l; + cl_object endp_temp; + + if (index < 0) + goto E; + switch (type_of(seq)) { + case t_cons: + for (i = index, l = seq; i > 0; --i) + if (endp(l)) + goto E; + else + l = CDR(l); + if (endp(l)) + goto E; + return(CAR(l) = val); + + case t_vector: + case t_bitvector: + if (index >= seq->vector.fillp) + goto E; + return(aset(seq, index, val)); + + case t_string: + if (index >= seq->string.fillp) + goto E; + /* INV: char_code() checks the type of `val' */ + seq->string.self[index] = char_code(val); + return(val); + + default: + FEerror("~S is not a sequence.", 1, seq); + } +E: + FEtype_error_index(MAKE_FIXNUM(index)); +} + +@(defun subseq (sequence start &optional end &aux x) + cl_fixnum s, e; + cl_fixnum i, j; +@ + s = fixnnint(start); + if (Null(end)) + e = -1; + else + e = fixnnint(end); + switch (type_of(sequence)) { + case t_symbol: + if (Null(sequence)) { + if (s > 0) + goto ILLEGAL_START_END; + if (e > 0) + goto ILLEGAL_START_END; + @(return Cnil) + } + FEwrong_type_argument(Ssequence, sequence); + + case t_cons: + if (e >= 0) + if ((e -= s) < 0) + goto ILLEGAL_START_END; + while (s-- > 0) { + if (ATOM(sequence)) + goto ILLEGAL_START_END; + sequence = CDR(sequence); + } + if (e < 0) + @(return `copy_list(sequence)`) + { cl_object *z = &x; + for (i = 0; i < e; i++) { + if (ATOM(sequence)) + goto ILLEGAL_START_END; + z = &CDR(*z = CONS(CAR(sequence), Cnil)); + sequence = CDR(sequence); + } + } + @(return x) + + case t_vector: + if (s > sequence->vector.fillp) + goto ILLEGAL_START_END; + if (e < 0) + e = sequence->vector.fillp; + else if (e < s || e > sequence->vector.fillp) + goto ILLEGAL_START_END; + x = alloc_simple_vector(e - s, sequence->vector.elttype); + array_allocself(x); + switch ((enum aelttype)sequence->vector.elttype) { + case aet_object: + case aet_fix: + case aet_sf: + for (i = s, j = 0; i < e; i++, j++) + x->vector.self.t[j] = sequence->vector.self.t[i]; + break; + + case aet_lf: + for (i = s, j = 0; i < e; i++, j++) + x->array.self.lf[j] = + sequence->array.self.lf[i]; + break; + default: + internal_error("subseq"); + } + @(return x) + + case t_string: + if (s > sequence->string.fillp) + goto ILLEGAL_START_END; + if (e < 0) + e = sequence->string.fillp; + else if (e < s || e > sequence->string.fillp) + goto ILLEGAL_START_END; + x = alloc_simple_string(e - s); + x->string.self = alloc_atomic(e - s + 1); + x->string.self[e-s] = '\0'; + for (i = s, j = 0; i < e; i++, j++) + x->string.self[j] = sequence->string.self[i]; + @(return x) + + case t_bitvector: + if (s > sequence->vector.fillp) + goto ILLEGAL_START_END; + if (e < 0) + e = sequence->vector.fillp; + else if (e < s || e > sequence->vector.fillp) + goto ILLEGAL_START_END; + x = alloc_simple_bitvector(e - s); + x->vector.self.bit = alloc_atomic((e-s+CHAR_BIT-1)/CHAR_BIT); + s += sequence->vector.offset; + e += sequence->vector.offset; + for (i = s, j = 0; i < e; i++, j++) + if (sequence->vector.self.bit[i/CHAR_BIT]&(0200>>i%CHAR_BIT)) + x->vector.self.bit[j/CHAR_BIT] + |= 0200>>j%CHAR_BIT; + else + x->vector.self.bit[j/CHAR_BIT] + &= ~(0200>>j%CHAR_BIT); + @(return x) + + default: + FEwrong_type_argument(Ssequence, x); + } + +ILLEGAL_START_END: + FEerror("~S and ~S are illegal as :START and :END~%\ +for the sequence ~S.", 3, start, end, sequence); +@) + +@(defun copy_seq (x) +@ + /* INV: #'subseq outputs only one value */ + return Lsubseq(2, x, MAKE_FIXNUM(0)); +@) + +@(defun length (x) +@ + @(return MAKE_FIXNUM(length(x))) +@) + +cl_fixnum +length(cl_object x) +{ + cl_fixnum i; + + switch (type_of(x)) { + case t_symbol: + if (Null(x)) + return(0); + FEwrong_type_argument(Ssequence, x); + + case t_cons: + /* INV: A list's length always fits in a fixnum */ + i = 0; + loop_for_in(x) { + i++; + } end_loop_for_in; + return(i); + + case t_vector: + case t_string: + case t_bitvector: + return(x->vector.fillp); + + default: + FEwrong_type_argument(Ssequence, x); + } +} + +@(defun reverse (x) +@ + @(return reverse(x)) +@) + +cl_object +reverse(cl_object seq) +{ + cl_object x, y, v; + int i, j, k; + cl_object endp_temp; + + switch (type_of(seq)) { + case t_symbol: + if (Null(seq)) + return(Cnil); + FEwrong_type_argument(Ssequence, seq); + + case t_cons: + v = Cnil; + for (x = seq; !endp(x); x = CDR(x)) + v = CONS(CAR(x), v); + return(v); + + case t_vector: + x = seq; + k = x->vector.fillp; + y = alloc_simple_vector(k, x->vector.elttype); + array_allocself(y); + switch ((enum aelttype)x->vector.elttype) { + case aet_object: + case aet_fix: + case aet_sf: + for (j = k - 1, i = 0; j >=0; --j, i++) + y->vector.self.t[j] = x->vector.self.t[i]; + break; + + case aet_lf: + for (j = k - 1, i = 0; j >=0; --j, i++) + y->array.self.lf[j] = x->array.self.lf[i]; + break; + default: + internal_error("reverse"); + } + return(y); + + case t_string: + x = seq; + y = alloc_simple_string(x->string.fillp); + y->string.self = alloc_atomic(x->string.fillp+1); + for (j = x->string.fillp - 1, i = 0; j >=0; --j, i++) + y->string.self[j] = x->string.self[i]; + y->string.self[x->string.fillp] = '\0'; + return(y); + + case t_bitvector: + x = seq; + y = alloc_simple_bitvector(x->vector.fillp); + y->vector.self.bit = alloc_atomic((x->vector.fillp+CHAR_BIT-1)/CHAR_BIT); + for (j = x->vector.fillp - 1, i = x->vector.offset; + j >=0; + --j, i++) + if (x->vector.self.bit[i/CHAR_BIT]&(0200>>i%CHAR_BIT)) + y->vector.self.bit[j/CHAR_BIT] |= 0200>>j%CHAR_BIT; + else + y->vector.self.bit[j/CHAR_BIT] &= ~(0200>>j%CHAR_BIT); + return(v); + + default: + FEwrong_type_argument(Ssequence, seq); + } +} + +@(defun nreverse (x) +@ + @(return nreverse(x)) +@) + +cl_object +nreverse(cl_object seq) +{ + cl_object x, y, z; + int i, j, k; + cl_object endp_temp; + + switch (type_of(seq)) { + case t_symbol: + if (Null(seq)) + return(Cnil); + FEwrong_type_argument(Ssequence, seq); + + case t_cons: + for (x = Cnil, y = seq; !endp(CDR(y));) { + z = y; + y = CDR(y); + CDR(z) = x; + x = z; + } + CDR(y) = x; + return(y); + + case t_vector: + x = seq; + k = x->vector.fillp; + switch ((enum aelttype)x->vector.elttype) { + case aet_object: + case aet_fix: + for (i = 0, j = k - 1; i < j; i++, --j) { + y = x->vector.self.t[i]; + x->vector.self.t[i] = x->vector.self.t[j]; + x->vector.self.t[j] = y; + } + return(seq); + + case aet_sf: + for (i = 0, j = k - 1; i < j; i++, --j) { + float y = x->array.self.sf[i]; + x->array.self.sf[i] = x->array.self.sf[j]; + x->array.self.sf[j] = y; + } + return(seq); + + case aet_lf: + for (i = 0, j = k - 1; i < j; i++, --j) { + double y = x->array.self.lf[i]; + x->array.self.lf[i] = x->array.self.lf[j]; + x->array.self.lf[j] = y; + } + return(seq); + default: + internal_error("subseq"); + } + + case t_string: + x = seq; + for (i = 0, j = x->string.fillp - 1; i < j; i++, --j) { + k = x->string.self[i]; + x->string.self[i] = x->string.self[j]; + x->string.self[j] = k; + } + return(seq); + + case t_bitvector: + x = seq; + for (i = x->vector.offset, + j = x->vector.fillp + x->vector.offset - 1; + i < j; + i++, --j) { + k = x->vector.self.bit[i/CHAR_BIT]&(0200>>i%CHAR_BIT); + if (x->vector.self.bit[j/CHAR_BIT]&(0200>>j%CHAR_BIT)) + x->vector.self.bit[i/CHAR_BIT] + |= 0200>>i%CHAR_BIT; + else + x->vector.self.bit[i/CHAR_BIT] + &= ~(0200>>i%CHAR_BIT); + if (k) + x->vector.self.bit[j/CHAR_BIT] + |= 0200>>j%CHAR_BIT; + else + x->vector.self.bit[j/CHAR_BIT] + &= ~(0200>>j%CHAR_BIT); + } + return(seq); + + default: + FEwrong_type_argument(Ssequence, seq); + } +} diff --git a/src/c/stacks.d b/src/c/stacks.d new file mode 100644 index 000000000..0e52363ce --- /dev/null +++ b/src/c/stacks.d @@ -0,0 +1,375 @@ +/* + stacks.c -- Binding/History/Frame stacks. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#ifdef HAVE_SYS_RESOURCE_H +# include +# include +#endif + +#ifndef THREADS +size_t bds_size; +bds_ptr bds_org; +bds_ptr bds_limit; +bds_ptr bds_top; + +size_t ihs_size; +ihs_ptr ihs_org; +ihs_ptr ihs_limit; +ihs_ptr ihs_top; + +size_t frs_size; +frame_ptr frs_org; +frame_ptr frs_limit; +frame_ptr frs_top; +frame_ptr nlj_fr; +cl_object nlj_tag; + +int *cs_org; +int *cs_limit; +size_t cssize; + +int NValues; +cl_object Values[VSSIZE]; +#endif + +cl_object Kcatch, Kcatchall, Kprotect; + +/********************* BINDING STACK ************************/ + +void +bds_overflow(void) +{ + --bds_top; + if (bds_limit > bds_org + bds_size) + error("bind stack overflow."); + bds_limit += BDSGETA; + FEerror("Bind stack overflow.", 0); +} + +void +bds_unwind(bds_ptr new_bds_top) +{ register bds_ptr bds = bds_top; + for (; bds > new_bds_top; bds--) + SYM_VAL(bds->bds_sym) = bds->bds_val; + bds_top = new_bds_top; +} + +static bds_ptr +get_bds_ptr(cl_object x) +{ + bds_ptr p; + + if (FIXNUMP(x)) { + p = bds_org + fix(x); + if (bds_org <= p && p <= bds_top) + return(p); + } + FEerror("~S is an illegal bds index.", 1, x); +} + +@(defun si::bds_top () +@ + @(return MAKE_FIXNUM(bds_top - bds_org)) +@) + +@(defun si::bds_var (arg) +@ + @(return get_bds_ptr(arg)->bds_sym) +@) + +@(defun si::bds_val (arg) +@ + @(return get_bds_ptr(arg)->bds_val) +@) + +/******************** INVOCATION STACK **********************/ + +void +ihs_overflow(void) +{ + --ihs_top; + if (ihs_limit > ihs_org + ihs_size) + error("invocation history stack overflow."); + ihs_limit += IHSGETA; + FEerror("Invocation history stack overflow.", 0); +} + +cl_object +ihs_function_name(cl_object x) +{ + cl_object y; + + switch (type_of(x)) { + case t_symbol: + return(x); + + case t_bytecodes: + y = x->bytecodes.data[0]; + if (Null(y)) + return(Slambda); + else + return y; + + case t_cfun: + return(x->cfun.name); + + default: + return(Cnil); + } +} + +cl_object +ihs_top_function_name(void) +{ + cl_object x; + ihs_ptr h = ihs_top; + + while (h >= ihs_org) { + x = ihs_function_name(h->ihs_function); + if (x != Cnil) + return(x); + h--; + } + return(Cnil); +} + +/* + Lisp interface to IHS +*/ + +static ihs_ptr +get_ihs_ptr(cl_object x) +{ + ihs_ptr p; + + if (FIXNUMP(x)) { + p = ihs_org + fix(x); + if (ihs_org <= p && p <= ihs_top) + return(p); + } + FEerror("~S is an illegal ihs index.", 1, x); +} + +@(defun si::ihs_top () +@ + @(return MAKE_FIXNUM(ihs_top - ihs_org)) +@) + +@(defun si::ihs_fun (arg) +@ + @(return get_ihs_ptr(arg)->ihs_function) +@) + +@(defun si::ihs_env (arg) + cl_object lex; +@ + lex = get_ihs_ptr(arg)->ihs_base; + @(return CONS(car(lex),cdr(lex))) +@) + +/********************** FRAME STACK *************************/ + +static int frame_id = 0; + +cl_object +new_frame_id(void) +{ + return(MAKE_FIXNUM(frame_id++)); +} + +int +frs_overflow(void) /* used as condition in list.d */ +{ + --frs_top; + if (frs_limit > frs_org + frs_size) + error("frame stack overflow."); + frs_limit += FRSGETA; + FEerror("Frame stack overflow.", 0); +} + +frame_ptr +_frs_push(register enum fr_class class, register cl_object val) +{ + if (++frs_top >= frs_limit) frs_overflow(); + frs_top->frs_lex = lex_env; + frs_top->frs_bds_top = bds_top; + frs_top->frs_class = class; + frs_top->frs_val = val; + frs_top->frs_ihs = ihs_top; + frs_top->frs_sp = stack->vector.fillp; + return frs_top; +} + +void +unwind(frame_ptr fr, cl_object tag) +{ + nlj_fr = fr; + nlj_tag = tag; + while (frs_top != fr + && frs_top->frs_class == FRS_CATCH) + --frs_top; + lex_env = frs_top->frs_lex; + ihs_top = frs_top->frs_ihs; + bds_unwind(frs_top->frs_bds_top); + stack->vector.fillp = frs_top->frs_sp; + ecls_longjmp(frs_top->frs_jmpbuf, 1); + /* never reached */ +} + +frame_ptr +frs_sch (cl_object frame_id) +{ + frame_ptr top; + + for (top = frs_top; top >= frs_org; top--) + if (top->frs_val == frame_id && top->frs_class == FRS_CATCH) + return(top); + return(NULL); +} + +frame_ptr +frs_sch_catch(cl_object frame_id) +{ + frame_ptr top; + + for(top = frs_top; top >= frs_org ;top--) + if ((top->frs_val == frame_id && top->frs_class == FRS_CATCH) + || top->frs_class == FRS_CATCHALL) + return(top); + return(NULL); +} + +static frame_ptr +get_frame_ptr(cl_object x) +{ + frame_ptr p; + + if (FIXNUMP(x)) { + p = frs_org + fix(x); + if (frs_org <= p && p <= frs_top) + return(p); + } + FEerror("~S is an illegal frs index.", 1, x); +} + +@(defun si::frs_top () +@ + @(return MAKE_FIXNUM(frs_top - frs_org)) +@) + +@(defun si::frs_bds (arg) +@ + @(return MAKE_FIXNUM(get_frame_ptr(arg)->frs_bds_top - bds_org)) +@) + +@(defun si::frs_class (arg) + enum fr_class c; + cl_object output; +@ + c = get_frame_ptr(arg)->frs_class; + if (c == FRS_CATCH) output = Kcatch; + else if (c == FRS_PROTECT) output = Kprotect; + else if (c == FRS_CATCHALL) output = Kcatchall; + else FEerror("Unknown frs class was detected.", 0); + @(return output) +@) + +@(defun si::frs_tag (arg) +@ + @(return get_frame_ptr(arg)->frs_val) +@) + +@(defun si::frs_ihs (arg) +@ + @(return MAKE_FIXNUM(get_frame_ptr(arg)->frs_ihs - ihs_org)) +@) + +@(defun si::sch_frs_base (fr ihs) + frame_ptr x; + ihs_ptr y; +@ + y = get_ihs_ptr(ihs); + for (x = get_frame_ptr(fr); x <= frs_top && x->frs_ihs < y; x++); + @(return ((x > frs_top) ? Cnil : MAKE_FIXNUM(x - frs_org))) +@) + +/********************* INITIALIZATION ***********************/ + +@(defun si::reset_stack_limits () +@ + if (bds_top < bds_org + (bds_size - 2*BDSGETA)) + bds_limit = bds_org + (bds_size - 2*BDSGETA); + else + error("can't reset bds_limit."); + if (frs_top < frs_org + (bds_size - 2*FRSGETA)) + frs_limit = frs_org + (frs_size - 2*FRSGETA); + else + error("can't reset frs_limit."); + if (ihs_top < ihs_org + (ihs_size - 2*IHSGETA)) + ihs_limit = ihs_org + (ihs_size - 2*IHSGETA); + else + error("can't reset ihs_limit."); +#ifdef DOWN_STACK + if (&narg > cs_org - cssize + 16) + cs_limit = cs_org - cssize; +#else + if (&narg < cs_org + cssize - 16) + cs_limit = cs_org + cssize; +#endif + else + error("can't reset cs_limit."); + + @(return Cnil) +@) + +void +alloc_stacks(int *new_cs_org) +{ +#ifdef THREADS + Values = main_lpd.lwp_Values; +#endif + + frs_size = FRSSIZE + 2*FRSGETA; + frs_org = alloc(frs_size * sizeof(*frs_org)); + frs_top = frs_org-1; + frs_limit = &frs_org[frs_size - 2*FRSGETA]; + bds_size = BDSSIZE + 2*BDSGETA; + bds_org = alloc(bds_size * sizeof(*bds_org)); + bds_top = bds_org-1; + bds_limit = &bds_org[bds_size - 2*BDSGETA]; + ihs_size = IHSSIZE + 2*IHSGETA; + ihs_org = alloc(ihs_size * sizeof(*ihs_org)); + ihs_top = ihs_org-1; + ihs_limit = &ihs_org[ihs_size - 2*IHSGETA]; + + cs_org = new_cs_org; +#if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_STACK) + { + struct rlimit rl; + getrlimit(RLIMIT_STACK, &rl); + cssize = rl.rlim_cur/4 - 4*CSGETA; + } +#else + cssize = CSSIZE; +#endif +#ifdef DOWN_STACK + cs_limit = cs_org - cssize; /* in THREADS I'm assigning to the main thread clwp */ +#else + cs_limit = cs_org + cssize; +#endif +} diff --git a/src/c/string.d b/src/c/string.d new file mode 100644 index 000000000..ad9c84375 --- /dev/null +++ b/src/c/string.d @@ -0,0 +1,683 @@ +/* + string.d -- String routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under thep terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include +#include +#include "ecls-inl.h" + +cl_object Kstart1; +cl_object Kend1; +cl_object Kstart2; +cl_object Kend2; +cl_object Kstart; +cl_object Kend; + +@(defun make_string (size &key (initial_element code_char(' ')) + (element_type Scharacter) + &aux x) + cl_index i, s, code; +@ + if (element_type != Scharacter + && element_type != Sbase_char + && element_type != Sstandard_char) { + if (_funcall(2, Ssubtypep, element_type, Scharacter) == Cnil) + FEerror("The type ~S is not a valid string char type.", + 1, element_type); + } + /* INV: char_code() checks the type of initial_element() */ + code = char_code(initial_element); + s = object_to_index(size); + x = alloc_simple_string(s); + x->string.self = alloc_atomic(s+1); + x->string.self[s] = '\0'; + for (i = 0; i < s; i++) + x->string.self[i] = code; + @(return x) +@) + +cl_object +alloc_simple_string(cl_index l) +{ + cl_object x; + + x = alloc_object(t_string); + x->string.hasfillp = FALSE; + x->string.adjustable = FALSE; + x->string.displaced = Cnil; + x->string.dim = (x->string.fillp = l) + 1; + x->string.self = NULL; + return(x); +} + +/* + Make a string of a certain size, with some eading zeros to + keep C happy. The string must be adjustable, to allow further + growth. (See unixfsys.c for its use). +*/ +cl_object +alloc_adjustable_string(cl_index l) +{ + cl_object output = alloc_simple_string(l); + output->string.self = alloc_atomic(l+1); + output->string.self[l] = output->string.self[0] = 0; + output->string.fillp = 0; + output->string.hasfillp = TRUE; + output->string.adjustable = TRUE; + return output; +} + +/* + Make_simple_string(s) makes a simple string from C string s. +*/ +cl_object +make_simple_string(char *s) +{ + cl_object x; + + x = alloc_simple_string(strlen(s)); + x->string.self = s; + + return(x); +} + +cl_object +make_string_copy(char *s) +{ + cl_object x; + cl_index l = strlen(s); + + x = alloc_simple_string(l); + x->string.self = alloc_atomic(l+1); + memcpy(x->string.self, s, l+1); + return(x); +} + + +/* + Copy_simple_string(x) copies string x to a simple string. +*/ +cl_object +copy_simple_string(cl_object x) +{ + cl_object y; + cl_index l = x->string.fillp; + + y = alloc_simple_string(l); + y->string.self = alloc_atomic(l+1); + memcpy(y->string.self, x->string.self, l); + y->string.self[l] = '\0'; + return(y); +} + +cl_object +coerce_to_string(cl_object x) +{ + cl_object y; + + switch (type_of(x)) { + case t_symbol: + return x->symbol.name; + + case t_character: + y = alloc_simple_string(1); + y->string.self = alloc_atomic(2); + y->string.self[1] = '\0'; + y->string.self[0] = CHAR_CODE(x); + return(y); + + case t_string: + return(x); + + default: + FEtype_error_string(x); + } +} + +/* + Outputs a valid string designator which is either a string or + a symbol, avoiding copying as far as possible. Characters are + coerced to strings. +*/ +cl_object +coerce_to_string_designator(cl_object x) +{ + cl_object y; + + switch (type_of(x)) { + case t_symbol: + return x->symbol.name; + + case t_string: + return x; + + case t_character: + y = alloc_simple_string(1); + y->string.self = alloc_atomic(2); + y->string.self[1] = '\0'; + y->string.self[0] = CHAR_CODE(x); + return(y); + + default: + FEtype_error_string(x); + } +} + +@(defun char (s i) + cl_index j; +@ + assert_type_string(s); + j = object_to_index(i); + /* CHAR bypasses fill pointers when accessing strings */ + if (j >= s->string.dim-1) + illegal_index(s, i); + @(return `code_char(s->string.self[j])`) +@) + +@(defun si::char_set (str index c) + cl_index j; +@ + assert_type_string(str); + j = object_to_index(index); + if (j >= str->string.fillp) + illegal_index(str, index); + /* INV: char_code() checks type of `c' */ + str->string.self[j] = char_code(c); + @(return c) +@) + +void +get_string_start_end(cl_object string, cl_object start, cl_object end, + cl_index *ps, cl_index *pe) +{ + /* INV: Works with either string or symbol */ + if (!FIXNUMP(start) || FIXNUM_MINUSP(start)) + goto E; + else + *ps = fix(start); + if (Null(end)) { + *pe = string->string.fillp; + if (*pe < *ps) + goto E; + } else if (!FIXNUMP(end) || FIXNUM_MINUSP(end)) + goto E; + else { + *pe = fix(end); + if (*pe < *ps || *pe > string->string.fillp) + goto E; + } + return; + +E: + FEerror("~S and ~S are illegal as :START and :END~%\ +for the string designator ~S.", 3, start, end, string); +} + +@(defun string_eq (string1 string2 &key (start1 MAKE_FIXNUM(0)) end1 + (start2 MAKE_FIXNUM(0)) end2) + cl_index s1, e1, s2, e2; +@ + string1 = coerce_to_string_designator(string1); + string2 = coerce_to_string_designator(string2); + get_string_start_end(string1, start1, end1, &s1, &e1); + get_string_start_end(string2, start2, end2, &s2, &e2); + if (e1 - s1 != e2 - s2) + @(return Cnil) + while (s1 < e1) + if (string1->string.self[s1++] != + string2->string.self[s2++]) + @(return Cnil) + @(return Ct) +@) + +/* + This correponds to string= (just the string equality). +*/ +bool +string_eq(cl_object x, cl_object y) +{ + /* INV: Works with either a symbol or a string */ + cl_index i, j; + i = x->string.fillp; + j = y->string.fillp; + return (i == j && strncmp(x->string.self, y->string.self, i) == 0); +} + + +@(defun string_equal (string1 string2 &key (start1 MAKE_FIXNUM(0)) end1 + (start2 MAKE_FIXNUM(0)) end2) + cl_index s1, e1, s2, e2; + cl_index i1, i2; +@ + string1 = coerce_to_string_designator(string1); + string2 = coerce_to_string_designator(string2); + get_string_start_end(string1, start1, end1, &s1, &e1); + get_string_start_end(string2, start2, end2, &s2, &e2); + if (e1 - s1 != e2 - s2) + @(return Cnil) + while (s1 < e1) { + i1 = string1->string.self[s1++]; + i2 = string2->string.self[s2++]; + if (toupper(i1) != toupper(i2)) + @(return Cnil) + } + @(return Ct) +@) + +/* + This corresponds to string-equal + (string equality ignoring the case). +*/ +bool +string_equal(cl_object x, cl_object y) +{ + cl_index i, j; + register char *p, *q; + + /* INV: Works with symbols ands strings */ + i = x->string.fillp; + j = y->string.fillp; + if (i != j) + return(FALSE); + p = x->string.self; + q = y->string.self; + for (i = 0; i < j; i++) + if (toupper(p[i]) != toupper(q[i])) + return(FALSE); + return(TRUE); +} + +cl_return +Lstring_cmp(int narg, int sign, int boundary, cl_object *ARGS) +{ + cl_object string1 = ARGS[0], string2 = ARGS[1]; + cl_index s1, e1, s2, e2; + int s, i1, i2; + cl_object KEYS[4]; +#define start1 KEY_VARS[0] +#define end1 KEY_VARS[1] +#define start2 KEY_VARS[2] +#define end2 KEY_VARS[3] +#define start1p KEY_VARS[4] +#define start2p KEY_VARS[6] + cl_object KEY_VARS[8]; + + if (narg < 2) FEtoo_few_arguments(&narg); + KEYS[0]=Kstart1; + KEYS[1]=Kend1; + KEYS[2]=Kstart2; + KEYS[3]=Kend2; + parse_key(narg-2, ARGS+2, 4, KEYS, KEY_VARS, OBJNULL, 0); + + string1 = coerce_to_string_designator(string1); + string2 = coerce_to_string_designator(string2); + if (start1p == Cnil) start1 = MAKE_FIXNUM(0); + if (start2p == Cnil) start2 = MAKE_FIXNUM(0); + get_string_start_end(string1, start1, end1, &s1, &e1); + get_string_start_end(string2, start2, end2, &s2, &e2); + while (s1 < e1) { + if (s2 == e2) + return1(sign>0 ? Cnil : MAKE_FIXNUM(s1)); + i1 = string1->string.self[s1]; + i2 = string2->string.self[s2]; + if (sign == 0) { + if (i1 != i2) + return1(MAKE_FIXNUM(s1)); + } else { + s = sign*(i2-i1); + if (s > 0) + return1(MAKE_FIXNUM(s1)); + if (s < 0) + return1(Cnil); + } + s1++; + s2++; + } + if (s2 == e2) + return1(boundary==0 ? MAKE_FIXNUM(s1) : Cnil); + else + return1(sign>=0 ? MAKE_FIXNUM(s1) : Cnil); +#undef start1p +#undef start2p +#undef start1 +#undef end1 +#undef start2 +#undef end2 +} + +cl_return +Lstring_l(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_cmp(narg, 1, 1, (cl_object *)args); } +cl_return +Lstring_g(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_cmp(narg,-1, 1, (cl_object *)args); } +cl_return +Lstring_le(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_cmp(narg, 1, 0, (cl_object *)args); } +cl_return +Lstring_ge(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_cmp(narg,-1, 0, (cl_object *)args); } +cl_return +Lstring_neq(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_cmp(narg, 0, 1, (cl_object *)args); } + + +cl_return +Lstring_compare(int narg, int sign, int boundary, cl_object *ARGS) +{ + cl_object string1 = ARGS[0], string2 = ARGS[1]; + cl_index s1, e1, s2, e2; + int i1, i2, s; + + cl_object KEYS[4]; +#define start1 KEY_VARS[0] +#define end1 KEY_VARS[1] +#define start2 KEY_VARS[2] +#define end2 KEY_VARS[3] +#define start1p KEY_VARS[4] +#define start2p KEY_VARS[6] + cl_object KEY_VARS[8]; + + if (narg < 2) FEtoo_few_arguments(&narg); + KEYS[0]=Kstart1; + KEYS[1]=Kend1; + KEYS[2]=Kstart2; + KEYS[3]=Kend2; + parse_key(narg-2, ARGS+2, 4, KEYS, KEY_VARS, OBJNULL, 0); + + string1 = coerce_to_string_designator(string1); + string2 = coerce_to_string_designator(string2); + if (start1p == Cnil) start1 = MAKE_FIXNUM(0); + if (start2p == Cnil) start2 = MAKE_FIXNUM(0); + get_string_start_end(string1, start1, end1, &s1, &e1); + get_string_start_end(string2, start2, end2, &s2, &e2); + while (s1 < e1) { + if (s2 == e2) + return1(sign>0 ? Cnil : MAKE_FIXNUM(s1)); + i1 = string1->string.self[s1]; + i1 = toupper(i1); + i2 = string2->string.self[s2]; + i2 = toupper(i2); + if (sign == 0) { + if (i1 != i2) + return1(MAKE_FIXNUM(s1)); + } else { + s = sign*(i2-i1); + if (s > 0) + return1(MAKE_FIXNUM(s1)); + if (s < 0) + return1(Cnil); + } + s1++; + s2++; + } + if (s2 == e2) + return1(boundary==0 ? MAKE_FIXNUM(s1) : Cnil); + else + return1(sign>=0 ? MAKE_FIXNUM(s1) : Cnil); +#undef start1p +#undef start2p +#undef start1 +#undef end1 +#undef start2 +#undef end2 +} + +cl_return +Lstring_lessp(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_compare(narg, 1, 1, (cl_object *)args); } +cl_return +Lstring_greaterp(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_compare(narg,-1, 1, (cl_object *)args); } +cl_return +Lstring_not_greaterp(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_compare(narg, 1, 0, (cl_object *)args); } +cl_return +Lstring_not_lessp(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_compare(narg,-1, 0, (cl_object *)args); } +cl_return +Lstring_not_equal(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_compare(narg, 0, 1, (cl_object *)args); } + +bool +member_char(int c, cl_object char_bag) +{ + cl_index i, f; + + switch (type_of(char_bag)) { + case t_cons: + loop_for_in(char_bag) { + cl_object other = CAR(char_bag); + if (CHARACTERP(other) && c == CHAR_CODE(other)) + return(TRUE); + char_bag = CDR(char_bag); + } end_loop_for_in; + return(FALSE); + + case t_vector: + for (i = 0, f = char_bag->vector.fillp; i < f; i++) { + cl_object other = char_bag->vector.self.t[i]; + if (CHARACTERP(other) && c == CHAR_CODE(other)) + return(TRUE); + } + return(FALSE); + + case t_string: + for (i = 0, f = char_bag->string.fillp; i < f; i++) { + if (c == char_bag->string.self[i]) + return(TRUE); + } + return(FALSE); + + case t_bitvector: + return(FALSE); + + default: + FEerror("~S is not a sequence.", 1, char_bag); + } +} + +cl_return +Lstring_trim(int narg, cl_object char_bag, cl_object strng) + { return Lstring_trim0(narg, TRUE, TRUE, char_bag, strng); } +cl_return +Lstring_left_trim(int narg, cl_object char_bag, cl_object strng) + { return Lstring_trim0(narg, TRUE, FALSE, char_bag, strng); } +cl_return +Lstring_right_trim(int narg, cl_object char_bag, cl_object strng) + { return Lstring_trim0(narg, FALSE, TRUE, char_bag, strng);} + +@(defun string_trim0(bool left_trim, bool right_trim) + (char_bag strng &aux res) + cl_index i, j, k; +@ + strng = coerce_to_string_designator(strng); + i = 0; + j = strng->string.fillp - 1; + if (left_trim) + for (; i <= j; i++) + if (!member_char(strng->string.self[i], char_bag)) + break; + if (right_trim) + for (; j >= i; --j) + if (!member_char(strng->string.self[j], char_bag)) + break; + k = j - i + 1; + res = alloc_simple_string(k); + res->string.self = alloc_atomic(k+1); + res->string.self[k] = '\0'; + memcpy(res->string.self, strng->string.self+i, k); + @(return res) +@) + +cl_return +Lstring_case(int narg, int (*casefun)(), cl_object *ARGS) +{ + cl_object strng = ARGS[0]; + cl_index s, e, i; + bool b; + cl_object KEYS[2]; +#define start KEY_VARS[0] +#define end KEY_VARS[1] +#define startp KEY_VARS[2] + cl_object conv; + cl_object KEY_VARS[4]; + + if (narg < 1) FEtoo_few_arguments(&narg); + KEYS[0]=Kstart; + KEYS[1]=Kend; + parse_key(narg-1, ARGS+1, 2, KEYS, KEY_VARS, OBJNULL, 0); + + strng = coerce_to_string_designator(strng); + conv = copy_simple_string(strng); + if (startp == Cnil) start = MAKE_FIXNUM(0); + get_string_start_end(conv, start, end, &s, &e); + b = TRUE; + for (i = s; i < e; i++) + conv->string.self[i] = (*casefun)(conv->string.self[i], &b); + return1(conv); +#undef startp +#undef start +#undef end +} + +static int char_upcase(int c, int *bp); +static int char_downcase(int c, int *bp); +static int char_capitalize(int c, int *bp); + +cl_return +Lstring_upcase(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_case(narg, char_upcase, (cl_object *)args); } + +static int +char_upcase(int c, int *bp) +{ + return(toupper(c)); +} + +cl_return +Lstring_downcase(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_case(narg, char_downcase, (cl_object *)args); } + +static int +char_downcase(int c, int *bp) +{ + return(tolower(c)); +} + +cl_return +Lstring_capitalize(int narg, ...) +{ va_list args; va_start(args, narg); + return Lstring_case(narg, char_capitalize, (cl_object *)args); } + +static int +char_capitalize(int c, int *bp) +{ + if (islower(c)) { + if (*bp) + c = toupper(c); + *bp = FALSE; + } else if (isupper(c)) { + if (!*bp) + c = tolower(c); + *bp = FALSE; + } else if (!isdigit(c)) + *bp = TRUE; + return(c); +} + + +cl_return +Lnstring_case(int narg, int (*casefun)(), cl_object *ARGS) +{ + cl_object strng = ARGS[0]; + cl_index s, e, i; + bool b; + cl_object KEYS[2]; +#define start KEY_VARS[0] +#define end KEY_VARS[1] +#define startp KEY_VARS[2] + cl_object KEY_VARS[4]; + + if (narg < 1) FEtoo_few_arguments(&narg); + KEYS[0]=Kstart; + KEYS[1]=Kend; + parse_key(narg-1, ARGS+1, 2, KEYS, KEY_VARS, OBJNULL, 0); + + assert_type_string(strng); + if (startp == Cnil) start = MAKE_FIXNUM(0); + get_string_start_end(strng, start, end, &s, &e); + b = TRUE; + for (i = s; i < e; i++) + strng->string.self[i] = (*casefun)(strng->string.self[i], &b); + return1(strng); +#undef startp +#undef start +#undef end +} + +cl_return +Lnstring_upcase(int narg, ...) +{ va_list args; va_start(args, narg); + return Lnstring_case(narg, char_upcase, (cl_object *)args); } +cl_return +Lnstring_downcase(int narg, ...) +{ va_list args; va_start(args, narg); + return Lnstring_case(narg, char_downcase, (cl_object *)args); } +cl_return +Lnstring_capitalize(int narg, ...) +{ va_list args; va_start(args, narg); + return Lnstring_case(narg, char_capitalize, (cl_object *)args); } + + +@(defun string (x) +@ + @(return `coerce_to_string(x)`) +@) + +@(defun si::string_concatenate (&rest args) + cl_index l; + int i; + cl_object v, *strings; + char *vself; +@ + strings = (cl_object *)args; + for (i = 0, l = 0; i < narg; i++) { + strings[i] = coerce_to_string_designator(va_arg(args, cl_object)); + l += strings[i]->string.fillp; + } + v = alloc_simple_string(l); + v->string.self = alloc_atomic(l+1); + v->string.self[l] = '\0'; + for (i = 0, vself = v->string.self; i < narg; i++, vself += l) { + l = strings[i]->string.fillp; + memcpy(vself, strings[i]->string.self, l); + } + @(return v) +@) diff --git a/src/c/structure.d b/src/c/structure.d new file mode 100644 index 000000000..e3025b653 --- /dev/null +++ b/src/c/structure.d @@ -0,0 +1,203 @@ +/* + structure.c -- Structure interface. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +cl_object siSstructure_print_function; +cl_object siSstructure_slot_descriptions; + +/******************************* ------- ******************************/ + +#ifdef CLOS +cl_object Sstructure_object; + +bool +structure_subtypep(cl_object x, cl_object y) +{ cl_object superiors; + if (CLASS_NAME(x) == y) + return(TRUE); + for (superiors=CLASS_SUPERIORS(x); superiors!=Cnil; + superiors=CDR(superiors)) { + if (structure_subtypep(CAR(superiors), y)) + return(TRUE); + } + return(FALSE); +} +#else +cl_object siSstructure_include; + +bool +structure_subtypep(cl_object x, cl_object y) +{ + do { + if (!SYMBOLP(x)) + return(FALSE); + if (x == y) + return(TRUE); + x = get(x, siSstructure_include, Cnil); + } while (x != Cnil); + return(FALSE); +} +#endif CLOS + +@(defun si::structure_subtype_p (x y) +@ + @(return ((type_of(x) == T_STRUCTURE + && structure_subtypep(STYPE(x), y)) ? Ct : Cnil)) +@) + +#ifndef CLOS +/* This is only used for printing. Should not cons!! */ +cl_object +structure_to_list(cl_object x) +{ + cl_object *p, r, s; + int i, n; + + s = getf(SNAME(x)->symbol.plist, + siSstructure_slot_descriptions, Cnil); + p = &CDR(r = CONS(SNAME(x), Cnil)); + for (i=0, n=SLENGTH(x); !endp(s) && i 0; --i) { + l = CDR(l); + if (endp(l)) FEtype_error_index(idx); + } + CAR(l) = v; + @(return v) +@) + +@(defun si::list_nth (idx x) +/* + Used in structure access functions generated by DEFSTRUCT. + si:list-nth is similar to nth except that + (si:list-nth i x) is error if the length of the list x is less than i. +*/ + cl_fixnum i; + cl_object l; +@ + assert_type_cons(x); + for (i = fixnnint(idx), l = x; i > 0; --i) { + l = CDR(l); + if (endp(l)) FEtype_error_index(idx); + } + @(return CAR(l)) +@) diff --git a/src/c/symbol.d b/src/c/symbol.d new file mode 100644 index 000000000..b0a0667e0 --- /dev/null +++ b/src/c/symbol.d @@ -0,0 +1,533 @@ +/* + symbol.d -- Symbols. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +#ifndef THREADS +cl_object gensym_prefix; +cl_object gentemp_prefix; +cl_object cl_token; +#endif THREADS + +struct symbol Cnil_body, Ct_body; +cl_object Vgensym_counter; + +/******************************* ------- ******************************/ + +cl_object siSpname; + +static cl_index gentemp_counter; + +@(defun make_symbol (str) +@ + assert_type_string(str); + @(return make_symbol(str)) +@) + +cl_object +make_symbol(cl_object st) +{ + cl_object x; + + x = alloc_object(t_symbol); + SYM_VAL(x) = OBJNULL; + /* FIXME! Should we copy? */ + x->symbol.name = st; + SYM_FUN(x) = OBJNULL; + x->symbol.plist = Cnil; + x->symbol.hpack = Cnil; + x->symbol.stype = stp_ordinary; + x->symbol.mflag = FALSE; + x->symbol.isform = FALSE; + return(x); +} + +/* + Make_ordinary(s) makes an ordinary symbol from C string s + and interns it in lisp package as an external symbol. +*/ +cl_object +make_ordinary(const char *s) +{ + cl_object x = _intern(s, lisp_package); + export(x, lisp_package); + return(x); +} + +/* + Make_special(s, v) makes a special variable from C string s + with initial value v in lisp package. +*/ +cl_object +make_special(const char *s, cl_object v) +{ + cl_object x = make_ordinary(s); + x->symbol.stype = (short)stp_special; + SYM_VAL(x) = v; + return(x); +} + +/* + Make_constant(s, v) makes a constant from C string s + with constant value v in lisp package. +*/ +cl_object +make_constant(const char *s, cl_object v) +{ + cl_object x = make_ordinary(s); + x->symbol.stype = (short)stp_constant; + SYM_VAL(x) = v; + return(x); +} + +/* + Make_si_ordinary(s) makes an ordinary symbol from C string s + and interns it in system package as an external symbol. +*/ +cl_object +make_si_ordinary(const char *s) +{ + cl_object x = _intern(s, system_package); + export(x, system_package); + return(x); +} + +/* + Make_si_special(s, v) makes a special variable from C string s + with initial value v in system package. +*/ +cl_object +make_si_special(const char *s, cl_object v) +{ + cl_object x = make_si_ordinary(s); + x->symbol.stype = (short)stp_special; + SYM_VAL(x) = v; + return(x); +} + +/* + Make_si_constant(s, v) makes a constant from C string s + with constant value v in system package. +*/ +cl_object +make_si_constant(const char *s, cl_object v) +{ + cl_object x = make_si_ordinary(s); + x->symbol.stype = (short)stp_constant; + SYM_VAL(x) = v; + return(x); +} + +/* + Make_keyword(s) makes a keyword from C string s. +*/ +cl_object +make_keyword(const char *s) +{ + cl_object x = _intern(s, keyword_package); + /* export(x, keyword_package); this is implicit in intern() */ + return x; +} + +cl_object +symbol_value(cl_object s) +{ + /* FIXME: Should we check symbol type? */ + if (SYM_VAL(s) == OBJNULL) + FEunbound_variable(s); + return(SYM_VAL(s)); +} + +cl_object +getf(cl_object place, cl_object indicator, cl_object deflt) +{ + cl_object slow, l; + + /* This loop guarantees finishing for circular lists */ + slow = l = place; + while (CONSP(l)) { + cl_object cdr_l = CDR(l); + if (!CONSP(cdr_l)) + FEtype_error_plist(place); + if (CAR(l) == indicator) + return CAR(cdr_l); + l = CDR(cdr_l); + slow = CDR(slow); + if (l == slow) + FEcircular_list(place); + } + if (l != Cnil) + FEtype_error_plist(place); + return(deflt); +} + +cl_object +get(cl_object s, cl_object p, cl_object d) +{ + if (!SYMBOLP(s)) + FEtype_error_symbol(s); + return(getf(s->symbol.plist, p, d)); +} + +/* + Putf(p, v, i) puts value v for property i to property list p + and returns the resulting property list. +*/ +cl_object +putf(cl_object place, cl_object value, cl_object indicator) +{ + cl_object slow, l; + + /* This loop guarantees finishing for circular lists */ + slow = l = place; + while (CONSP(l)) { + cl_object cdr_l = CDR(l); + if (!CONSP(cdr_l)) + FEtype_error_plist(place); + if (CAR(l) == indicator) { + CAR(cdr_l) = value; + return place; + } + l = CDR(cdr_l); + slow = CDR(slow); + if (l == slow) + FEcircular_list(place); + } + if (l != Cnil) + FEtype_error_plist(place); + place = CONS(value, place); + return CONS(indicator, place); +} + +cl_object +putprop(cl_object s, cl_object v, cl_object p) +{ + if (!SYMBOLP(s)) + FEtype_error_symbol(s); + s->symbol.plist = putf(s->symbol.plist, v, p); + return(v); +} + +/* + Remf(p, i) removes property i + from the property list pointed by p, + which is a pointer to an cl_object. + The returned value of remf(p, i) is: + + TRUE if the property existed + FALSE otherwise. +*/ +bool +remf(cl_object *place, cl_object indicator) +{ + cl_object *slow, *l; + + /* This loop guarantees finishing for circular lists */ + slow = l = place; + while (CONSP(*l)) { + cl_object cdr_l = CDR(*l); + if (!CONSP(cdr_l)) + FEtype_error_plist(*place); + if (CAR(*l) == indicator) { + *l = CDR(cdr_l); + return TRUE; + } + l = &CDR(cdr_l); + slow = &CDR(*slow); + if (l == slow) + FEcircular_list(*place); + } + if (*l != Cnil) + FEtype_error_plist(*place); + return(FALSE); +} + +cl_object +remprop(cl_object s, cl_object p) +{ + if (!SYMBOLP(s)) + FEtype_error_symbol(s); + if (remf(&s->symbol.plist, p)) + return(Ct); + else + return(Cnil); +} + +bool +keywordp(cl_object s) +{ + return (SYMBOLP(s) && s->symbol.hpack == keyword_package); +} + +@(defun get (sym indicator &optional deflt) +@ + assert_type_symbol(sym); + @(return getf(sym->symbol.plist, indicator, deflt)) +@) + +@(defun remprop (sym prop) +@ + assert_type_symbol(sym); + @(return (remf(&sym->symbol.plist, prop)? Ct: Cnil)) +@) + +@(defun symbol_plist (sym) +@ + assert_type_symbol(sym); + @(return sym->symbol.plist) +@) + +@(defun getf (place indicator &optional deflt) +@ + @(return getf(place, indicator, deflt)) +@) + +@(defun get_properties (place indicator_list) + cl_object slow, cdr_l, l; +@ + /* This loop guarantees finishing for circular lists */ + for (slow = l = place; CONSP(l); ) { + cdr_l = CDR(l); + if (!CONSP(cdr_l)) + FEtype_error_plist(place); + if (member_eq(CAR(l), indicator_list)) + @(return CAR(l) CADR(l) l) + l = CDR(cdr_l); + slow = CDR(slow); + if (l == slow) + FEcircular_list(place); + } + if (l != Cnil) + FEtype_error_plist(place); + @(return Cnil Cnil Cnil) +@) + +cl_object +symbol_name(cl_object x) +{ + assert_type_symbol(x); + return x->symbol.name; +} + +@(defun symbol_name (sym) +@ + @(return symbol_name(sym)) +@) + +@(defun copy_symbol (sym &optional cp &aux x) +@ + assert_type_symbol(sym); + x = make_symbol(sym); + if (Null(cp)) + @(return x) + x->symbol.stype = sym->symbol.stype; + SYM_VAL(x) = SYM_VAL(sym); + x->symbol.mflag = sym->symbol.mflag; + SYM_FUN(x) = SYM_FUN(sym); + x->symbol.plist = copy_list(sym->symbol.plist); + @(return x) +@) + +@(defun gensym (&optional (x gensym_prefix) &aux str) + cl_index name_length, j, counter_value; + volatile cl_object counter; +@ + if (type_of(x) == t_string) { + gensym_prefix = x; + counter = SYM_VAL(Vgensym_counter); + } else + counter = x; + if (!FIXNUMP(counter) || FIXNUM_MINUSP(counter)) { + FEerror("*gensym-counter*, ~A, not a positive fixnum", + 1, counter); + } + counter_value = fix(counter); + name_length = gensym_prefix->string.fillp; + for (j = counter_value; j > 0; j /= 10) + name_length++; + if (name_length == 0) + name_length++; + str = alloc_simple_string(name_length); + str->string.self = alloc_atomic(name_length+1); + str->string.self[name_length] = '\0'; + for (j = 0; j < gensym_prefix->string.fillp; j++) + str->string.self[j] = gensym_prefix->string.self[j]; + if (counter_value == 0) + str->string.self[--name_length] = '0'; + else + for (j=counter_value; j > 0; j /= 10) + str->string.self[--name_length] = j%10 + '0'; + SYM_VAL(Vgensym_counter) = MAKE_FIXNUM(counter_value+1); + @(return make_symbol(str)) +@) + +@(defun gentemp (&optional (prefix gentemp_prefix) + (pack `current_package()`) + &aux str smbl) + size_t name_length, j; +@ + assert_type_string(prefix); + assert_type_package(pack); +ONCE_MORE: + name_length = prefix->string.fillp; + for (j = gentemp_counter; j > 0; j /= 10) + name_length++; + if (name_length == 0) + name_length++; + str = alloc_simple_string(name_length); + str->string.self = alloc_atomic(name_length+1); + str->string.self[name_length] = '\0'; + for (j = 0; j < prefix->string.fillp; j++) + str->string.self[j] = prefix->string.self[j]; + if ((j = gentemp_counter) == 0) + str->string.self[--name_length] = '0'; + else + for (; j > 0; j /= 10) + str->string.self[--name_length] = j%10 + '0'; + gentemp_counter++; + smbl = intern(str, pack); + if (intern_flag != 0) + goto ONCE_MORE; + @(return smbl) +@) + +@(defun symbol_package (sym) +@ + assert_type_symbol(sym); + @(return sym->symbol.hpack) +@) + +@(defun keywordp (sym) +@ + @(return ((SYMBOLP(sym) && keywordp(sym))? Ct: Cnil)) +@) + +/* + (SI:PUT-F plist value indicator) + returns the new property list with value for property indicator. + It will be used in SETF for GETF. +*/ +@(defun si::put_f (plist value indicator) +@ + @(return putf(plist, value, indicator)) +@) + +/* + (SI:REM-F plist indicator) returns two values: + + * the new property list + in which property indcator is removed + + * T if really removed + NIL otherwise. + + It will be used for macro REMF. +*/ +@(defun si::rem_f (plist indicator) + bool found; +@ + found = remf(&plist, indicator); + @(return plist (found? Ct : Cnil)) +@) + +@(defun si::set_symbol_plist (sym plist) +@ + assert_type_symbol(sym); + sym->symbol.plist = plist; + @(return plist) +@) + +@(defun si::putprop (sym value indicator) +@ + assert_type_symbol(sym); + sym->symbol.plist = putf(sym->symbol.plist, value, indicator); + @(return value) +@) + +/* Added for defstruct. Beppe */ +@(defun si::put_properties (sym &rest ind_values) + cl_object prop; +@ + while (--narg >= 2) { + prop = va_arg(ind_values, cl_object); + putprop(sym, va_arg(ind_values, cl_object), prop); + narg--; + } + @(return sym) +@) + +@(defun si::Amake_special (sym) +@ + assert_type_symbol(sym); + if ((enum stype)sym->symbol.stype == stp_constant) + FEerror("~S is a constant.", 1, sym); + sym->symbol.stype = (short)stp_special; + remf(&sym->symbol.plist, siSsymbol_macro); + @(return sym) +@) + +@(defun si::Amake_constant (sym val) +@ + assert_type_symbol(sym); + if ((enum stype)sym->symbol.stype == stp_special) + FEerror( + "The argument ~S to DEFCONSTANT is a special variable.", + 1, sym); + sym->symbol.stype = (short)stp_constant; + SYM_VAL(sym) = val; + @(return sym) +@) + +void +init_symbol(void) +{ + Cnil_body.t = (short)t_symbol; + Cnil_body.dbind = Cnil; + Cnil_body.name = make_simple_string("NIL"); + Cnil_body.gfdef = OBJNULL; + Cnil_body.plist = Cnil; + Cnil_body.hpack = Cnil; + Cnil_body.stype = (short)stp_constant; + Cnil_body.mflag = FALSE; + Cnil_body.isform = FALSE; + + Ct_body.t = (short)t_symbol; + Ct_body.dbind = Ct; + Ct_body.name = make_simple_string("T"); + Ct_body.gfdef = OBJNULL; + Ct_body.plist = Cnil; + Ct_body.hpack = Cnil; + Ct_body.stype = (short)stp_constant; + Ct_body.mflag = FALSE; + Ct_body.isform = FALSE; + + gensym_prefix = make_simple_string("G"); + gentemp_prefix = make_simple_string("T"); + gentemp_counter = 0; + cl_token = alloc_simple_string(LISP_PAGESIZE); + cl_token->string.fillp = 0; + cl_token->string.self = alloc_atomic(LISP_PAGESIZE); + cl_token->string.hasfillp = TRUE; + cl_token->string.adjustable = TRUE; + + register_root(&gensym_prefix); + register_root(&gentemp_prefix); + register_root(&cl_token); +} + diff --git a/src/c/tclBasic.d b/src/c/tclBasic.d new file mode 100644 index 000000000..8eb0cbb0f --- /dev/null +++ b/src/c/tclBasic.d @@ -0,0 +1,786 @@ +/* + * + * tclBasic. c - A library replacement for simulating + * a Tcl interpreter in ECoLisp + * + * Copyright (C) 1993,1994,1995 Erick Gallesio - I3S-CNRS/ESSI + * + * + * Permission to use, copy, and/or distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that both the above copyright notice and this permission notice appear in + * all copies and derived works. Fees for distribution or use of this + * software or derived works may only be charged with express written + * permission of the copyright holder. + * This software is provided ``as is'' without express or implied warranty. + * + * This software is a derivative work of other copyrighted softwares; the + * copyright notices of these softwares are placed in the file COPYRIGHTS + * + * + * Author: Erick Gallesio [eg@unice.fr] + * Creation date: 19-Feb-1993 22:15 + * Last file update: 11-Feb-1995 15:07 + * + * Modified for ECL by Giuseppe Attardi [attardi@di.unipi.it] + * + */ + +#include "ecls.h" +#include "tk.h" +#include "tclInt.h" + +cl_object TkWidgetType; +Tcl_Interp *ECL_interp; + +extern cl_object tk_package; + +static Tcl_HashTable VarTable; /* Global hash table retaining traced variables */ + +#define STRING_INPUT_STREAM(s, strm) \ + struct stream strm; \ + struct string string; \ + string.t = (short)t_string; \ + string.m = FALSE; \ + string.st_hasfillp = FALSE; \ + string.st_adjustable = FALSE; \ + string.st_displaced = Cnil; \ + string.st_dim = (string.st_fillp = strlen(s)) + 1; \ + string.st_self = s; \ + strm.t = (short)t_stream; \ + strm.m = FALSE; \ + strm.sm_mode = (short)smm_string_input; \ + strm.sm_fp = NULL; \ + strm.sm_object0 = (cl_object)&string; \ + strm.sm_object1 = OBJNULL; \ + strm.sm_int0 = 0; \ + strm.sm_int1 = string.st_fillp + +static cl_object +eval_from_string(char *s) +{ + cl_object x; + STRING_INPUT_STREAM(s, strm); + x = Lread(3, (cl_object)&strm, Cnil, OBJNULL); + return (x != OBJNULL) ? eval(x, NULL) : Cnil; +} + +static cl_object string_stream; +static char char_string[2] = { 0, 0}; +static char *empty = "()"; + +static char * +object2string(cl_object x) +{ + extern VOID *malloc(); + switch (type_of(x)) { + case t_string: + case t_symbol: + if (x == Cnil) + return(empty); + else + return(x->string.self); + case t_fixnum: { + char *num = malloc(12); + sprintf(num, "%d", fix(x)); + return(num); + } + case t_character: { + char_string[0] = char_code(x); + return char_string; + } + case t_cons: { + extern cl_object siVprint_package; + string_stream->stream.object0->string.fillp = 0; + string_stream->stream.int0 = string_stream->stream.int1 = 0; + bds_bind(siVprint_package, Ct); + prin1(x, string_stream); + bds_unwind1; + return(string_stream->stream.object0->string.self); + } + case t_pathname: + return namestring(x)->string.self; + case t_shortfloat: { + char *num = malloc(12); + sprintf(num, "%f", sf(x)); + return(num); + } + case t_longfloat: { + char *num = malloc(12); + sprintf(num, "%f", lf(x)); + return(num); + } + case t_ratio: { + char *num = malloc(12); + if (FIXNUMP(x->ratio.num) && FIXNUMP(x->ratio.den)) { + sprintf(num, "%d", fix(x->ratio.num) / fix(x->ratio.den)); + return(num); + } + break; + } + } + FEerror("~S cannot be coerced to a C string.", 1, x); +} + +/***************************************************************************** + * + * Eval functions + * + *****************************************************************************/ + +int +Tcl_GlobalEval(Tcl_Interp *interp, char *s) +{ + cl_object result; + + if (*s == '\0') return TCL_OK; + + /* In some situations Tk appends some data (numbers) to the callback. This + * arise for scrollbars and scales. These parameters are normally used to + * reflect slider position. When such a situation arises, we have to + * specify the callback as a string and add a pair of parenthesis around + * this string to form a valid sexpr. To recognize such cases, we look + * at first character: if it is not an open parenthesis, we add a pair of () + * around the callback string + * + */ + + if (*s != '(') { + /* Build the command to evaluate by adding a pair of parenthesis */ + char buffer[strlen(s)+3]; /* __GNUC__ */ + sprintf(buffer, "(%s)", s); + result = eval_from_string(buffer); + } + else result = eval_from_string(s); + /* we might use TCL_DYNAMIC if object_to_string used malloc */ + Tcl_SetResult(interp, object2string(result), TCL_STATIC); + return TCL_OK; +} + +/* very simplistic. But do we need something more clever? */ +int +Tcl_Eval(Tcl_Interp *interp, char *s) +{ + return Tcl_GlobalEval(interp, s); +} + +int +Tcl_VarEval(Tcl_Interp *interp, /* Interpreter in which to execute command */ + ...) /* One or more strings to concatenate, + terminated with a NULL string. */ +{ + va_list argList; +#define FIXED_SIZE 200 + char fixedSpace[FIXED_SIZE+1]; + int spaceAvl, spaceUsed, length; + char *string, *cmd; + int result; + + /* + * Copy the strings one after the other into a single larger + * string. Use stack-allocated space for small commands, but if + * the commands gets too large than call ckalloc to create the + * space. + */ + + va_start(argList, interp); + spaceAvl = FIXED_SIZE; + spaceUsed = 0; + cmd = fixedSpace; + while (TRUE) { + string = va_arg(argList, char *); + if (string == NULL) { + break; + } + length = strlen(string); + if ((spaceUsed + length) > spaceAvl) { + char *new; + + spaceAvl = spaceUsed + length; + spaceAvl += spaceAvl/2; + new = ckalloc((unsigned) spaceAvl); + memcpy((VOID *) new, (VOID *) cmd, spaceUsed); + if (cmd != fixedSpace) { + ckfree(cmd); + } + cmd = new; + } + strcpy(cmd + spaceUsed, string); + spaceUsed += length; + } + va_end(argList); + cmd[spaceUsed] = '\0'; + + result = Tcl_GlobalEval(interp, cmd); + if (cmd != fixedSpace) { + ckfree(cmd); + } + return result; +} + + +static void +upcase(char *s, char *d) +{ + for ( ; *s != '\0'; s++) + *d++ = toupper(*s); + *d = '\0'; +} + +/***************************************************************************** + * + * Variable accesses (GetVar, GetVar2, SetVar, SetVar2) + * + *****************************************************************************/ + +char * +Tcl_GetVar(Tcl_Interp *interp, char *var, int flags) +{ + cl_object V; + char VAR[strlen(var)+1]; /* __GNUC__ */ + upcase(var, VAR); + V = SYM_VAL(_intern(VAR, tk_package)); + return (V == OBJNULL) ? NULL : object2string(V); +} + +char * +Tcl_GetVar2(Tcl_Interp *interp, char *name1, char *name2, int flags) +{ + if (name2 && *name2) { + char *res; + char s[strlen(name1) + strlen(name2) + 8]; /* __GNUC__ */ + + sprintf(s, "(AREF %s %s)", name1, name2); + Tcl_GlobalEval(interp, s); + return interp->result; + } + return Tcl_GetVar(interp, name1, flags); +} + +char * +Tcl_SetVar(Tcl_Interp *interp, char *var, char *val, int flags) +{ + char VAR[strlen(var)+1]; /* __GNUC__ */ + upcase(var, VAR); + /* Eval the following expression: (setq var val) */ + SYM_VAL(_intern(VAR, tk_package)) = make_simple_string(val); +/* Tcl_ChangeValue(var); in tcl-trace.c */ + return val; +} + +char * +Tcl_SetVar2(Tcl_Interp *interp, char *name1, char *name2, char *val, + int flags) +{ + if (name2 && *name2) { + char *res; + char s[strlen(name1) + strlen(name2) + 16]; /* __GNUC__ */ + + sprintf(s, "(SETF (AREF %s %s) %s)", name1, name2); + Tcl_GlobalEval(interp, s); + return interp->result; + } + return Tcl_SetVar(interp, name1, val, flags); +} + +/***************************************************************************** + * + * Tcl command management + * + *****************************************************************************/ + +int +Tcl_DeleteCommand(Tcl_Interp *interp, char *cmdName) +{ + cl_object V = _intern(cmdName, tk_package); + + if (SYM_FUN(V) == OBJNULL) return -1; + SYM_FUN(V) = OBJNULL; /* Undefine "cmdName" */ + SYM_VAL(V) = OBJNULL; /* Undefine "cmdName" */ + return 0; +} + +/* ECL should use lowercase symbols as default!!! + In such case we could read with: + + STRING_INPUT_STREAM(s, strm); + Lread(3, (cl_object)&strm, Cnil, OBJNULL); + result = VALUES(0); + Lread(3, (cl_object)&strm, Cnil, OBJNULL); + if (VALUES(0) != OBJNULL) { + result = CONS(result, Cnil); + for (p = &CDR(result) ; ; p = &(CDR(*p))) { + *p = CONS(VALUES(0), Cnil); + Lread(3, (cl_object)&strm, Cnil, OBJNULL); + if (VALUES(0) == OBJNULL) break; + } + } + */ +static cl_object +parse_from_string(struct string *s, char **ep) +{ + if (isdigit(s->st_self[0])) { + int n; + cl_object num = parse_number(s->st_self, s->st_fillp, &n, 10); + *ep = s->st_self + n; + return num; + } + else { + *ep = s->st_self + s->st_fillp; + (cl_object)s = copy_simple_string(s); + s->st_self[s->st_fillp] = '\0'; + return (cl_object)s; + } +} + +/* We must return strings since commands like 'text index 1.0+1c' return + indexes (e.g. 1.1) which should not be converted to numbers*/ +static cl_object +TkResult2Lisp(Tcl_Interp *interp) +{ + register char *s = interp->result; + register cl_object result = Cnil, *p; + extern cl_object Tk_root_window; + + if (strcmp(s, ".") == 0) return Tk_root_window; + if (*s) { + int i; + char *e; + struct stream strm; + struct string string; + string.t = (short)t_string; + string.m = FALSE; + string.st_hasfillp = FALSE; + string.st_adjustable = FALSE; + string.st_displaced = Cnil; + string.st_self = s; + + e = strchr(s, ' '); + if (e == NULL) { + string.st_dim = (string.st_fillp = strlen(s))+1; + result = copy_simple_string(&string); + } else { + /* Result was a list of values, build a proper list */ + string.st_dim = (string.st_fillp = e-s)+1; + *e = '\0'; + result = CONS(copy_simple_string(&string), Cnil); + for (p = &CDR(result) ; ; p = &(CDR(*p))) { + s = e+1; + string.st_self = s; + e = strchr(s, ' '); + if (e == NULL) { + string.st_dim = (string.st_fillp = strlen(s))+1; + *p = CONS(copy_simple_string(&string), Cnil); + break; + } + string.st_dim = (string.st_fillp = e-s)+1; + *e = '\0'; + *p = CONS(copy_simple_string(&string), Cnil); + } + } + } + Tcl_ResetResult(interp); + return result; +} + +#ifdef NEW +static cl_object +TkResult2Lisp(Tcl_Interp *interp) +{ + register char *s = interp->result; + register cl_object result = Cnil, *p; + extern cl_object Tk_root_window; + + if (strcmp(s, ".") == 0) return Tk_root_window; + if (*s) { + int i; + char *e; + struct stream strm; + struct string string; + string.t = (short)t_string; + string.m = FALSE; + string.st_hasfillp = FALSE; + string.st_adjustable = FALSE; + string.st_displaced = Cnil; + string.st_self = s; + + e = strchr(s, ' '); + if (e == NULL) { + string.st_dim = (string.st_fillp = strlen(s))+1; + result = parse_from_string(&string, &e); + } else { + /* Result was a list of values, build a proper list */ + string.st_dim = (string.st_fillp = e-s)+1; + result = CONS(parse_from_string(&string, &e), Cnil); + for (p = &CDR(result) ; ; p = &(CDR(*p))) { + s = e+1; + string.st_self = s; + e = strchr(s, ' '); + if (e == NULL) { + string.st_dim = (string.st_fillp = strlen(s))+1; + *p = CONS(parse_from_string(&string, &e), Cnil); + break; + } + string.st_dim = (string.st_fillp = e-s)+1; + *p = CONS(parse_from_string(&string, &e), Cnil); + } + } + } + Tcl_ResetResult(interp); + return result; +} +#endif + +tclMethodDispatch(int narg, cl_object env, ...) +{ + va_list args; + cl_object W = CAR(env); + char *argv[narg]; + int i; + Tcl_CmdProc *proc = (Tcl_CmdProc *)fix(SLOT(W, 0)); + ClientData clientData = (ClientData)fix(SLOT(W, 1)); + argv[0] = SLOT(W, 2)->symbol.name->string.self; /* command name */ + va_start(args, env); + for (i = 1; i < narg; i++) + argv[i] = object2string(va_arg(args, cl_object)); + /* if previous result was a symbol, proc could not write to interp->result + * so we must clear it + */ + Tcl_ResetResult(ECL_interp); + if ((*proc)(clientData, ECL_interp, narg, argv) == TCL_ERROR) + VALUES(0) = (cl_object)FEerror(ECL_interp->result, 0); + else + VALUES(0) = TkResult2Lisp(ECL_interp); + return(1); +} + +void +Tcl_CreateCommand(Tcl_Interp *interp, char *cmdName, Tcl_CmdProc *proc, + ClientData clientData, + Tcl_CmdDeleteProc *deleteProc) +{ + cl_object SYM, sym, W; + char CMDNAME[strlen(cmdName)+1]; /* __GNUC__ */ + + sym = _intern(cmdName, tk_package); + /* Define a variable whose name is the command name */ + upcase(cmdName, CMDNAME); + SYM = _intern(CMDNAME, tk_package); + SYM_VAL(SYM) = sym; /* evaluating to lower case symbol */ + siLmake_structure(4, TkWidgetType, MAKE_FIXNUM(proc), + MAKE_FIXNUM(clientData), sym); + W = VALUES(0); + + /* Define a function whose name is the command name */ + SYM_FUN(sym) = (cl_object)make_cclosure(tclMethodDispatch, CONS(W, Cnil), NULL); + SYM_FUN(SYM) = SYM_FUN(sym); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetCommandInfo -- + * + * Returns various information about a Tcl command. + * + * Results: + * If cmdName exists in interp, then *infoPtr is modified to + * hold information about cmdName and 1 is returned. If the + * command doesn't exist then 0 is returned and *infoPtr isn't + * modified. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_GetCommandInfo(Tcl_Interp *interp, /* Interpreter in which to look + * for command. */ + char *cmdName, /* Name of desired command. */ + Tcl_CmdInfo *infoPtr) /* Where to store information about + * command. */ +{ + cl_object v = _intern(cmdName, tk_package); + + if (!structure_subtypep(TYPE_OF(SYM_VAL(v)), TkWidgetType)) return 0; + + infoPtr->proc = (Tcl_CmdProc *)fix(SLOT(SYM_VAL(v), 0)); + infoPtr->clientData = (ClientData)fix(SLOT(SYM_VAL(v), 1)); + infoPtr->deleteProc = NULL; + infoPtr->deleteData = NULL; + return 1; +} + + +/***************************************************************************** + * + * Tcl interpreter management + * + *****************************************************************************/ + +Tcl_Interp * +Tcl_CreateInterp() +{ + register Interp *iPtr = (Interp *) ckalloc(sizeof(Interp)); + + iPtr->result = iPtr->resultSpace; + iPtr->freeProc = 0; + iPtr->errorLine = 0; + iPtr->resultSpace[0] = 0; + + iPtr->appendResult = NULL; + iPtr->appendAvl = 0; + iPtr->appendUsed = 0; + + strcpy(iPtr->pdFormat, "%g"); + + return (Tcl_Interp *) iPtr; +} + +void +Tcl_DeleteInterp(Tcl_Interp *interp) +{ + Interp *iPtr = (Interp *) interp; + + if (iPtr->appendResult != NULL) { + ckfree(iPtr->appendResult); + } + ckfree((char *) iPtr); +} + +init_tk() +{ +#ifdef CLOS + TkWidgetType = define a class with name: _intern("WIDGET", tk_package); +#else + TkWidgetType = _intern("WIDGET", tk_package); +#endif + string_stream = make_string_output_stream(64); + register_root(&string_stream); + Tcl_InitHashTable(&VarTable, TCL_STRING_KEYS); +} + +/* + * Dummies + */ +int +Tcl_Init(Tcl_Interp *interp) +{} + +void +Tcl_CallWhenDeleted( + Tcl_Interp *interp, /* Interpreter to watch. */ + Tcl_InterpDeleteProc *proc, /* Procedure to call when interpreter + * is about to be deleted. */ + ClientData clientData) /* One-word value to pass to proc. */ +{} + +void +Tcl_DontCallWhenDeleted(interp, proc, clientData) + Tcl_Interp *interp; /* Interpreter to watch. */ + Tcl_InterpDeleteProc *proc; /* Procedure to call when interpreter + * is about to be deleted. */ + ClientData clientData; /* One-word value to pass to proc. */ +{} + +int +Tcl_SetCommandInfo(interp, cmdName, infoPtr) + Tcl_Interp *interp; /* Interpreter in which to look + * for command. */ + char *cmdName; /* Name of desired command. */ + Tcl_CmdInfo *infoPtr; /* Where to store information about + * command. */ +{} + +Tcl_Trace +Tcl_CreateTrace(interp, level, proc, clientData) + Tcl_Interp *interp; /* Interpreter in which to create the trace. */ + int level; /* Only call proc for commands at nesting level + * <= level (1 => top level). */ + Tcl_CmdTraceProc *proc; /* Procedure to call before executing each + * command. */ + ClientData clientData; /* Arbitrary one-word value to pass to proc. */ +{} + +void +Tcl_DeleteTrace(interp, trace) + Tcl_Interp *interp; /* Interpreter that contains trace. */ + Tcl_Trace trace; /* Token for trace (returned previously by + * Tcl_CreateTrace). */ +{} + +void +Tcl_AddErrorInfo(interp, message) + Tcl_Interp *interp; /* Interpreter to which error information + * pertains. */ + char *message; /* Message to record. */ +{} + +int +Tcl_SetRecursionLimit(interp, depth) + Tcl_Interp *interp; /* Interpreter whose nesting limit + * is to be set. */ + int depth; /* New value for maximimum depth. */ +{} + +/*---------------------------------------------------------------------- + * from tclVar.c + *---------------------------------------------------------------------- + */ + +int +Tcl_TraceVar(interp, varName, flags, proc, clientData) + Tcl_Interp *interp; /* Interpreter in which variable is + * to be traced. */ + char *varName; /* Name of variable; may end with "(index)" + * to signify an array reference. */ + int flags; /* OR-ed collection of bits, including any + * of TCL_TRACE_READS, TCL_TRACE_WRITES, + * TCL_TRACE_UNSETS, and TCL_GLOBAL_ONLY. */ + Tcl_VarTraceProc *proc; /* Procedure to call when specified ops are + * invoked upon varName. */ + ClientData clientData; /* Arbitrary argument to pass to proc. */ +{ + Tcl_HashEntry *entry; + int new; + struct VarTrace *data; + + entry = Tcl_CreateHashEntry(&VarTable, varName, &new); + + /* Create the value associated to the "var" key */ + data= (struct VarTrace *) ckalloc((unsigned) sizeof (struct VarTrace)); + data->flags = flags & ~TCL_TRACE_UNSETS; /* Unset has no meaning in ECL */ + data->traceProc = proc; + data->clientData = clientData; + data->nextPtr = (VarTrace *) (new ? NULL : Tcl_GetHashValue(entry)); + + /* Put it in table */ + Tcl_SetHashValue(entry, (ClientData) data); + + return TCL_OK; +} + + +int +Tcl_TraceVar2(interp, part1, part2, flags, proc, clientData) + Tcl_Interp *interp; /* Interpreter in which variable is + * to be traced. */ + char *part1; /* Name of scalar variable or array. */ + char *part2; /* Name of element within array; NULL means + * trace applies to scalar variable or array + * as-a-whole. */ + int flags; /* OR-ed collection of bits, including any + * of TCL_TRACE_READS, TCL_TRACE_WRITES, + * TCL_TRACE_UNSETS, and TCL_GLOBAL_ONLY. */ + Tcl_VarTraceProc *proc; /* Procedure to call when specified ops are + * invoked upon varName. */ + ClientData clientData; /* Arbitrary argument to pass to proc. */ +{ + if (*part2) { + + } + return Tcl_TraceVar(interp, part1, flags, proc, clientData); +} + +void +Tcl_UntraceVar(interp, varName, flags, proc, clientData) + Tcl_Interp *interp; /* Interpreter containing traced variable. */ + char *varName; /* Name of variable; may end with "(index)" + * to signify an array reference. */ + int flags; /* OR-ed collection of bits describing + * current trace, including any of + * TCL_TRACE_READS, TCL_TRACE_WRITES, + * TCL_TRACE_UNSETS, and TCL_GLOBAL_ONLY. */ + Tcl_VarTraceProc *proc; /* Procedure assocated with trace. */ + ClientData clientData; /* Arbitrary argument to pass to proc. */ +{ + Tcl_HashEntry *entry; + register VarTrace *p, *prev; + + if (entry = Tcl_FindHashEntry(&VarTable, varName)) { + /* Variable is traced. Try to find correponding trace function */ + flags &= ~TCL_TRACE_UNSETS; /* Unset has no meaning for us */ + + p = (struct VarTrace *) Tcl_GetHashValue(entry); + for (prev=NULL; p ; prev=p, p=p->nextPtr) { + if (p->traceProc == proc && p->flags == flags && p->clientData == clientData) + break; + } + if (p) { + if (prev == NULL) { + if (p->nextPtr) + Tcl_SetHashValue(entry, (ClientData *) p->nextPtr); + else + Tcl_DeleteHashEntry(entry); + } + else + prev->nextPtr = p->nextPtr; + ckfree(p); + } + } +} + +void +Tcl_UntraceVar2(interp, part1, part2, flags, proc, clientData) + Tcl_Interp *interp; /* Interpreter containing traced variable. */ + char *part1; /* Name of variable or array. */ + char *part2; /* Name of element within array; NULL means + * trace applies to scalar variable or array + * as-a-whole. */ + int flags; /* OR-ed collection of bits describing + * current trace, including any of + * TCL_TRACE_READS, TCL_TRACE_WRITES, + * TCL_TRACE_UNSETS, and TCL_GLOBAL_ONLY. */ + Tcl_VarTraceProc *proc; /* Procedure assocated with trace. */ + ClientData clientData; /* Arbitrary argument to pass to proc. */ +{ + if (part2 && *part2) { + char *s = malloc(strlen(part1) + strlen(part2) + 3); + + sprintf(s, "%s{%s}", part1, part2); + Tcl_UntraceVar(interp, s, flags, proc, clientData); + free(s); + } + else + Tcl_UntraceVar(interp, part1, flags, proc, clientData); +} + +/**** + * + * Tcl_ChangeValue + * + * This function is called by Lisp when a there's a global variable change + * (using a tk-setq). "var" is a C string indicating the name of this + * variable. If this variable is traced, call the C functions associated to it. + * + ****/ + +#define TRACING (1<<20) + +void Tcl_ChangeValue(char *var) +{ + Tcl_HashEntry *entry; + register VarTrace *data, *p; + extern int Tk_initialized; + + if (!Tk_initialized) return; + + if (entry = Tcl_FindHashEntry(&VarTable, var)) { + /* Variable is traced. Call all the associated traces */ + data = (struct VarTrace *) Tcl_GetHashValue(entry); + + for (p = data; p ; p = p->nextPtr) { + /* Invoke trace procedure if not already active */ + if (p->flags & TRACING) + continue; + + p->flags |= TRACING; + (*p->traceProc)(p->clientData, ECL_interp, var, "", p->flags); + + /* Unset our flag */ + p->flags &= ~TRACING; + } + } +} diff --git a/src/c/tcp.d b/src/c/tcp.d new file mode 100644 index 000000000..bba5bdb00 --- /dev/null +++ b/src/c/tcp.d @@ -0,0 +1,114 @@ +/* tcp.c -- stream interface to TCP */ + +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or modify it + under the terms of the GNU General Library Public License as published + by the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + See file '../Copyright' for full details. +*/ + +#include "ecls.h" + +cl_object +make_stream(cl_object host, int fd, enum smmode smm) +{ + cl_object stream; + char *mode; /* file open mode */ + FILE *fp; /* file pointer */ + + switch(smm) { + case smm_input: + mode = "r"; + break; + case smm_output: + mode = "w"; + break; + default: + FEerror("make_stream: wrong mode", 0); + } + fp = fdopen(fd, mode); + + stream = alloc_object(t_stream); + stream->stream.mode = (short)smm; + stream->stream.file = fp; + stream->stream.object0 = Sbase_char; + stream->stream.object1 = host; /* not really used */ + stream->stream.int0 = stream->stream.int1 = 0; +#if !defined(GBC_BOEHM) + fp->_IO_buf_base = NULL; /* BASEFF */; + setbuf(fp, stream->stream.buffer = alloc_atomic(BUFSIZ)); +#endif + return(stream); +} + +/* + Lopen_client_stream -- + + To test this function, try: + (setq s (si:open-client-stream "host" 13)) + (read-line s) + "Wed Jun 22 19:44:36 METDST 1994" +*/ +@(defun open_client_stream (host port) + int fd; /* file descriptor */ + cl_object streamIn, streamOut; +@ + if (type_of(host) != t_string) + FEwrong_type_argument(Sstring, host); + + if (!FIXNUMP(port)) + FEwrong_type_argument(TSpositive_number, port); + + /* FIXME! Why? */ + if (host->string.fillp > BUFSIZ - 1) + FEerror("~S is a too long file name.", 1, host); + +#ifdef THREADS + start_critical_section(); +#endif THREADS + fd = connect_to_server(host->string.self, fix(port)); +#ifdef THREADS + end_critical_section(); +#endif THREADS + + if (fd == 0) + @(return Cnil) + + streamIn = make_stream(host, fd, smm_input); + streamOut = make_stream(host, fd, smm_output); + + @(return make_two_way_stream(streamIn, streamOut)) +@) + +@(defun open_server_stream (port) + int fd; /* file descriptor */ + cl_object streamIn, streamOut; + cl_object output; +@ + if (!FIXNUMP(port)) + FEwrong_type_argument(TSpositive_number, port); + +#ifdef THREADS + start_critical_section(); +#endif THREADS + fd = create_server_port(fix(port)); +#ifdef THREADS + end_critical_section(); +#endif THREADS + + if (fd == 0) + output = Cnil; + else { + streamIn = make_stream(Cnil, fd, smm_input); + streamOut = make_stream(Cnil, fd, smm_output); + output = make_two_way_stream(streamIn, streamOut); + } + @(return output) +@) + + diff --git a/src/c/time.d b/src/c/time.d new file mode 100644 index 000000000..478f59c9b --- /dev/null +++ b/src/c/time.d @@ -0,0 +1,161 @@ +/* + time.c -- Time routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include +#include +#include +#include + +#ifndef HZ /* usually from */ +#define HZ 60 +#endif + +static time_t beginning; + +int +runtime(void) +/* + tms_utime is the CPU time used while executing instructions in the + user space of the calling process, measured in 1/HZ seconds. +*/ +{ + struct tms buf; + + times(&buf); + return(buf.tms_utime); +} + +static cl_object Jan1st1970UT; + +cl_object +UTC_time_to_universal_time(int i) +{ + return number_plus(bignum1(i), Jan1st1970UT); +} + +@(defun get_universal_time () +@ + @(return UTC_time_to_universal_time(time(0))) +@) + +@(defun sleep (z) + double r; + struct timespec tm; +@ + /* INV: number_minusp() makes sure `z' is real */ + if (number_minusp(z)) + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Not a non-negative number ~S"), + Kformat_arguments, list(1, z), + Kexpected_type, Sreal, Kdatum, z); +#ifdef HAVE_NANOSLEEP + r = object_to_double(z); + tm.tv_sec = (time_t)floor(r); + tm.tv_nsec = (long)((r - floor(r)) * 1e9); + nanosleep(&tm, NULL); +#else + z = round1(z); + if (FIXNUMP(z)) + sleep(fix(z)); + else + for(;;) + sleep(1000); +#endif + @(return Cnil) +@) + +@(defun get_internal_run_time () + struct tms buf; +@ + times(&buf); + @(return MAKE_FIXNUM(buf.tms_utime)) +@) + +@(defun get_internal_real_time () +@ + @(return MAKE_FIXNUM((time(0) - beginning)*HZ)) +@) + +/* + * Return the hours west of Greenwich for the current timezone. + * + * Based on Lott's get_timezone() function from CMU Common Lisp. + */ +@(defun get_local_time_zone () + struct tm ltm, gtm; + int mw; + time_t when = 0L; +@ + ltm = *localtime(&when); + gtm = *gmtime(&when); + + mw = (gtm.tm_min + 60 * gtm.tm_hour) - (ltm.tm_min + 60 * ltm.tm_hour); + + if ((gtm.tm_wday + 1) % 7 == ltm.tm_wday) + mw -= 24*60; + else if (gtm.tm_wday == (ltm.tm_wday + 1) % 7) + mw += 24*60; + + @(return make_ratio(MAKE_FIXNUM(mw), MAKE_FIXNUM(60))) +@) + +/* + * Return T if daylight saving is in effect at Universal Time UT, which + * defaults to current time. + * + */ +@(defun daylight_saving_timep (&rest args) + struct tm *ltm; + time_t when; +@ + if (narg == 0) + when = time(0); + else if (narg == 1) { + cl_object UT, UTC; + va_start(args, narg); + UT = va_arg(args, cl_object); + UTC = number_minus(UT, Jan1st1970UT); + switch (type_of(UTC)) { + case t_fixnum: + when = fix(UTC); + break; + case t_bignum: + when = big_to_long(UTC); + break; + default: + FEerror("Universal Time out of range: ~A.", 1, UT); + } + } + else + FEtoo_many_arguments(&narg); + ltm = localtime(&when); + @(return (ltm->tm_isdst ? Ct : Cnil)) +@) + +void +init_unixtime(void) +{ + beginning = time(0); + + make_si_special("*DEFAULT-TIME-ZONE*", MAKE_FIXNUM(TIME_ZONE)); + make_constant("INTERNAL-TIME-UNITS-PER-SECOND", MAKE_FIXNUM(HZ)); + + Jan1st1970UT = + number_times(MAKE_FIXNUM(24 * 60 * 60), + MAKE_FIXNUM(17 + 365 * 70)); + register_root(&Jan1st1970UT); +} diff --git a/src/c/tkMain.d b/src/c/tkMain.d new file mode 100644 index 000000000..38f77843c --- /dev/null +++ b/src/c/tkMain.d @@ -0,0 +1,210 @@ +/* + * tkMain.c -- Initialization of Tk + * + * This code initializes the Tk library. It corresponds to a part of the + * file main.c of the wish interpreter. + * + * Author: Erick Gallesio [eg@unice.fr] + * Creation date: 13-May-1993 10:59 + * Last file update: 10-Feb-1995 22:23 + * + * + * Code used here was originally copyrigthed as shown below: + * Copyright 1990-1992 Regents of the University of California. + * + * + * Copyright (C) 1993,1994,1995 Erick Gallesio - I3S-CNRS/ESSI + * + * + * Permission to use, copy, and/or distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that both the above copyright notice and this permission notice appear in + * all copies and derived works. Fees for distribution or use of this + * software or derived works may only be charged with express written + * permission of the copyright holder. + * This software is provided ``as is'' without express or implied warranty. + * + * This software is a derivative work of other copyrighted softwares; the + * copyright notices of these softwares are placed in the file COPYRIGHTS + * + * Modified for ECL by Giuseppe Attardi [attardi@di.unipi.it] + * + */ + +#include "ecls.h" +#include "tk.h" + + +/* + * Command used to initialize ECL/tk: + */ + +static char initCmd[] = +"(tk::tk-init)"; + +/* + * Global variables used by the main program: + */ + +static Tk_Window w; /* The main window for the application. If + * NULL then the application no longer + * exists. */ +Tcl_Interp *ECL_interp = NULL; /* Interpreter for this application. */ +int Tk_initialized = FALSE; /* TRUE when Tk is fully initialized */ +cl_object Tk_root_window; + +/* + * Forward declarations for procedures defined later in this file: + */ + +static void DelayedMap _ANSI_ARGS_((ClientData clientData)); +static void StructureProc _ANSI_ARGS_((ClientData clientData, + XEvent *eventPtr)); + +extern StdinResume(); +extern cl_object tk_package; + + +/* + *---------------------------------------------------------------------- + * + * Tk_main + * + *---------------------------------------------------------------------- + */ + +void +Tk_main(int synchronize, char *name, char *fileName, char *Xdisplay, + char *geometry) +{ + Tk_3DBorder border; + + ECL_interp = Tcl_CreateInterp(); + + /* + * Parse command-line arguments. + */ + + Tcl_SetVar(ECL_interp, "*geometry*", geometry ? geometry : "", + TCL_GLOBAL_ONLY); + + /* + * Initialize the Tk application and arrange to map the main window + * after the startup script has been executed, if any. This way + * the script can withdraw the window so it isn't ever mapped + * at all. + */ + + w = Tk_CreateMainWindow(ECL_interp, Xdisplay, name, "ECL/Tk"); + if (w == NULL) { + fprintf(stderr, "%s\n", ECL_interp->result); + exit(1); + } + + Tcl_SetVar(ECL_interp, "*root*", ".", TCL_GLOBAL_ONLY); + Tk_root_window = _intern("*ROOT*", tk_package); + + Tk_CreateEventHandler(w, StructureNotifyMask, StructureProc, + (ClientData) NULL); + Tk_DoWhenIdle(DelayedMap, (ClientData) NULL); + if (synchronize) { + XSynchronize(Tk_Display(w), True); + } + Tk_GeometryRequest(w, 200, 200); + border = Tk_Get3DBorder(ECL_interp, w, None, "#cccccc"); + if (border == NULL) { + Tcl_SetResult(ECL_interp, (char *) NULL, TCL_STATIC); + Tk_SetWindowBackground(w, WhitePixelOfScreen(Tk_Screen(w))); + } + else { + Tk_SetBackgroundFromBorder(w, border); + } + XSetForeground(Tk_Display(w), DefaultGCOfScreen(Tk_Screen(w)), + BlackPixelOfScreen(Tk_Screen(w))); + + Tk_initialized = 1; /* Ok, it's fully initialized */ + + /* + * Set up a handler for stdin, for resuming read when input + * becomes available + */ + Tk_CreateFileHandler(0, TK_READABLE, (Tk_FileProc *)StdinResume, + (ClientData) 0); + StdinEnableEvents(); /* check for events when idle */ + + /* + * Set the geometry of the main window, if requested. + */ + if (geometry != NULL) { + if (TCL_OK != Tcl_VarEval(ECL_interp, "(wm 'geometry *root* '", + geometry, ")", NULL)) + fprintf(stderr, "**** Warning: %s\n", ECL_interp->result); + } + + /* + * Execute ECL/Tk's initialization script, followed by the script specified + * on the command line, if any. + */ + + Tcl_GlobalEval(ECL_interp, initCmd); +} + + +/* + *---------------------------------------------------------------------- + * + * StructureProc -- + * + * This procedure is invoked whenever a structure-related event + * occurs on the main window. If the window is deleted, the + * procedure modifies "w" to record that fact. + * + * Results: + * None. + * + * Side effects: + * Variable "w" may get set to NULL. + * + *---------------------------------------------------------------------- + */ + +static void +StructureProc(ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ +{ + if (eventPtr->type == DestroyNotify) + w = NULL; +} + +/* + *---------------------------------------------------------------------- + * + * DelayedMap -- + * + * This procedure is invoked by the event dispatcher once the + * startup script has been processed. It waits for all other + * pending idle handlers to be processed (so that all the + * geometry information will be correct), then maps the + * application's main window. + * + * Results: + * None. + * + * Side effects: + * The main window gets mapped. + * + *---------------------------------------------------------------------- + */ + +static void +DelayedMap(ClientData clientData) +{ + + while (Tk_DoOneEvent(TK_IDLE_EVENTS) != 0) { + /* Empty loop body. */ + } + if (w == NULL) { + return; + } + Tk_MapWindow(w); +} diff --git a/src/c/typespec.d b/src/c/typespec.d new file mode 100644 index 000000000..b43170718 --- /dev/null +++ b/src/c/typespec.d @@ -0,0 +1,427 @@ +/* + typespec.c -- Type specifier routines. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" + +/******************************* EXPORTS ******************************/ + +cl_object Squote; +cl_object Slambda; +cl_object Sspecial; + +cl_object Ssubtypep; + +cl_object +St, Snil, Scommon, Ssequence, +Snull, Scons, Slist, Ssymbol, +Sarray, Svector, Sbit_vector, Sstring, +Ssimple_array, Ssimple_vector, Ssimple_string, Ssimple_bit_vector, +Sfunction, Spathname, Scharacter, Scompiled_function, +Snumber, Srational, Sfloat, Sreal, +Sinteger, Sratio, Sshort_float, Sstandard_char, +Sfixnum, Scomplex, Ssingle_float, Spackage, +Sbignum, Srandom_state, Sdouble_float, Sstream, +Sbit, Sreadtable, Slong_float, Shash_table, +Ssigned_char, Sunsigned_char, Ssigned_short, Sunsigned_short, +Sbase_char, Sextended_char, Slogical_pathname; + +#ifdef THREADS +cl_object Scont, Sthread; +#endif THREADS + +#ifdef CLOS +cl_object Sinstance, Sdispatch_function; +#endif + +#ifdef LOCATIVE +cl_object Slocative; +#endif + +cl_object Sstructure, Ssatisfies, Smember, Snot, Sor, Sand; +cl_object Svalues, Smod, Ssigned_byte, Sunsigned_byte; + +cl_object SX; /* symbol * */ +cl_object Splusp; + +cl_object TSnon_negative_integer; +cl_object TSpositive_number; + +/******************************* ------- ******************************/ + +cl_object Skeyword; + +/**********************************************************************/ + +void +FEtype_error_character(cl_object x) { + FEwrong_type_argument(Scharacter, x); +} + +void +FEtype_error_cons(cl_object x) { + FEwrong_type_argument(Scons, x); +} + +void +FEtype_error_number(cl_object x) { + FEwrong_type_argument(Snumber, x); +} + +void +FEtype_error_real(cl_object x) { + FEwrong_type_argument(Sreal, x); +} + +void +FEtype_error_float(cl_object x) { + FEwrong_type_argument(Sfloat, x); +} + +void +FEtype_error_integer(cl_object x) { + FEwrong_type_argument(Sinteger, x); +} + +void +FEtype_error_list(cl_object x) { + FEwrong_type_argument(Slist, x); +} + +void +FEtype_error_proper_list(cl_object x) { + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Not a proper list ~D"), + Kformat_arguments, list(1, x), + Kexpected_type, Slist, + Kdatum, x); +} + +void +FEtype_error_alist(cl_object x) +{ + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Not a valid association list ~D"), + Kformat_arguments, list(1, x), + Kexpected_type, Slist, + Kdatum, x); +} + +void +FEtype_error_plist(cl_object x) +{ + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Not a valid property list ~D"), + Kformat_arguments, list(1, x), + Kexpected_type, Slist, + Kdatum, x); +} + +void +FEcircular_list(cl_object x) +{ + /* FIXME: Is this the right way to rebind it? */ + bds_bind(Vprint_circle, Ct); + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Circular list ~D"), + Kformat_arguments, list(1, x), + Kexpected_type, Slist, + Kdatum, x); +} + +void +FEtype_error_index(cl_object x) +{ + FEcondition(9, Ssimple_type_error, Kformat_control, + make_simple_string("Index out of bounds ~D"), + Kformat_arguments, list(1, x), + Kexpected_type, Sfixnum, + Kdatum, x); +} + +void +FEtype_error_string(cl_object s) +{ + FEwrong_type_argument(Sstring, s); +} + +void +FEtype_error_stream(cl_object strm) +{ + FEwrong_type_argument(Sstream, strm); +} + +/**********************************************************************/ + +void +assert_type_integer(cl_object p) +{ + enum type t = type_of(p); + if (t != t_fixnum && t != t_bignum) + FEtype_error_integer(p); +} + +void +assert_type_non_negative_integer(cl_object p) +{ + enum type t = type_of(p); + + if (t == t_fixnum) { + if (FIXNUM_PLUSP(p)) + return; + } else if (t == t_bignum) { + if (big_sign(p) >= 0) + return; + } + FEwrong_type_argument(TSnon_negative_integer, p); +} + +void +assert_type_character(cl_object p) +{ + if (!CHARACTERP(p)) + FEtype_error_character(p); +} + +void +assert_type_symbol(cl_object p) +{ + if (!SYMBOLP(p)) + FEwrong_type_argument(Ssymbol, p); +} + +void +assert_type_package(cl_object p) +{ + if (type_of(p) != t_package) + FEwrong_type_argument(Spackage, p); +} + +void +assert_type_string(cl_object p) +{ + if (type_of(p) != t_string) + FEtype_error_string(p); +} + +void +assert_type_cons(cl_object p) +{ + if (ATOM(p)) + FEwrong_type_argument(Scons, p); +} + +void +assert_type_list(cl_object p) +{ + if (ATOM(p) && p != Cnil) + FEtype_error_list(p); +} + +void +assert_type_proper_list(cl_object p) +{ + if (ATOM(p) && p != Cnil) + FEtype_error_list(p); + if (list_length(p) == Cnil) + FEcircular_list(p); +} + +void +assert_type_stream(cl_object p) +{ + if (type_of(p) != t_stream) + FEwrong_type_argument(Sstream, p); +} + +void +assert_type_readtable(cl_object p) +{ + if (type_of(p) != t_readtable) + FEwrong_type_argument(Sreadtable, p); +} + +void +assert_type_hash_table(cl_object p) +{ + if (type_of(p) != t_hashtable) + FEwrong_type_argument(Shash_table, p); +} + +void +assert_type_array(cl_object p) +{ + if (!ARRAYP(p)) + FEwrong_type_argument(Sarray, p); +} + +void +assert_type_vector(cl_object p) +{ + if (!VECTORP(p)) + FEwrong_type_argument(Svector, p); +} + +cl_object +TYPE_OF(cl_object x) +{ + switch (type_of(x)) { +#ifdef CLOS + case t_instance: + { cl_object cl = CLASS_OF(x); + if (CLASS_NAME(cl) != Cnil) + return(CLASS_NAME(cl)); + else + return(cl); + } +#endif + + case t_fixnum: + return(Sfixnum); + + case t_bignum: + return(Sbignum); + + case t_ratio: + return(Sratio); + + case t_shortfloat: + return(Sshort_float); + + case t_longfloat: + return(Slong_float); + + case t_complex: + return(Scomplex); + + case t_character: { + int i = CHAR_CODE(x); + if ((' ' <= i && i < '\177') || i == '\n') + return(Sstandard_char); + else + return(Sbase_char); + } + + case t_symbol: + if (x == Cnil) + return(Snull); + if (x->symbol.hpack == keyword_package) + return(Skeyword); + else + return(Ssymbol); + + case t_package: + return(Spackage); + + case t_cons: + return(Scons); + + case t_hashtable: + return(Shash_table); + + case t_array: + if (x->array.adjustable || + Null(CAR(x->array.displaced))) + return(Sarray); + else + return(Ssimple_array); + + case t_vector: + if (x->vector.adjustable || + x->vector.hasfillp || + Null(CAR(x->vector.displaced)) || + (enum aelttype)x->vector.elttype != aet_object) + return(Svector); + else + return(Ssimple_vector); + + case t_string: + if (x->string.adjustable || + x->string.hasfillp || + Null(CAR(x->string.displaced))) + return(Sstring); + else + return(Ssimple_string); + + case t_bitvector: + if (x->vector.adjustable || + x->vector.hasfillp || + Null(CAR(x->vector.displaced))) + return(Sbit_vector); + else + return(Ssimple_bit_vector); + +#ifndef CLOS + case t_structure: + return(x->str.name); +#endif CLOS + + case t_stream: + return(Sstream); + + case t_readtable: + return(Sreadtable); + + case t_pathname: + if (x->pathname.logical) + return Slogical_pathname; + return(Spathname); + + case t_random: + return(Srandom_state); + + case t_bytecodes: + case t_cfun: + case t_cclosure: + return(Scompiled_function); + +#ifdef THREADS + case t_cont: + return(Scont); + + case t_thread: + return(Sthread); +#endif THREADS +#ifdef CLOS + case t_gfun: + return(Sdispatch_function); +#endif +#ifdef LOCATIVE + case t_locative: + return(Slocative); +#endif + + default: + error("not a lisp data object"); + } +} + +@(defun type_of (x) +@ + @(return TYPE_OF(x)) +@) + +void +init_typespec(void) +{ + + TSnon_negative_integer + = CONS(Sinteger, + CONS(MAKE_FIXNUM(0), CONS(SX, Cnil))); + register_root(&TSnon_negative_integer); + TSpositive_number = CONS(Ssatisfies, CONS(Splusp, Cnil)); + register_root(&TSpositive_number); +} diff --git a/src/c/unify.d b/src/c/unify.d new file mode 100644 index 000000000..402e6c418 --- /dev/null +++ b/src/c/unify.d @@ -0,0 +1,298 @@ +/* + unify.d -- Support for unification. +*/ +/* + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include "unify.h" + +object *slot; /* scanning pointer within object */ +int (*slotf)(); /* read/write mode accessor */ + +/* -------------------- Trail Instructions -------------------- */ + +object *trail[VSSIZE]; +object **trail_top = trail; + +#define BIND(loc, val) {loc = val; trail_push(&loc);} + +@(defun trail_mark () +@ + trail_mark; +@) + +@(defun trail_restore () +@ + trail_restore; + @(return Cnil) +@) + +@(defun trail_unmark () +@ + trail_unmark; + @(return Cnil) +@) + +/* -------------------- Mode Operators -------------------- */ + +bool get_slot(object x) /* read mode */ +{ + if (x == *slot || unify(x, *slot)) + if (*slot == OBJNULL) + return((bool)MAKE_LOCATIVE(slot++)); + else + return((bool)*slot++); /* dereference */ + else + return(FALSE); +} + +bool set_slot(object x) /* write mode */ +{ + /* NOTE: slot contains OBJNULL */ + *slot = x; + return((bool)MAKE_LOCATIVE(slot++)); +} + + +/* -------------------- Get Instructions -------------------- */ + +/* get_variable is just setq */ + +@(defun get_value (v x) +@ + @(return `get_value(v, x)?Ct:Cnil`) +@) + +@(defun get_constant (c x) +@ + @(return `get_constant(c, x)?Ct:Cnil`) +@) + +@(defun get_nil (arg) +@ + @(return `get_nil(arg)?Ct:Cnil`) +@) + +bool +get_cons(object x) +{ + +RETRY: switch (type_of(x)) { + case t_cons: + slot = &CDR(x); /* cdr slot is first in struct cons */ + slotf = get_slot; + return(TRUE); + + case t_locative: + if (UNBOUNDP(x)) { + object new = CONS(OBJNULL, OBJNULL); + BIND(DEREF(x), new); + slot = &CDR(new); + slotf = set_slot; + return(TRUE); + } + else { + x = DEREF(x); + goto RETRY; + } + + default: return(FALSE); + } + +} + +@(defun get_cons (arg) +@ + @(return `get_cons(arg)?Ct:Cnil`) +@) + +bool +get_instance(object x, object class, int arity) +{ +RETRY: switch (type_of(x)) { + case t_instance: + if (CLASS_OF(x) == class) { + slot = x->instance.slots; + slotf = get_slot; + return(TRUE); + } else + return(FALSE); + + case t_locative: + if (UNBOUNDP(x)) { + object new = allocate_instance(class, arity); + BIND(DEREF(x), new); + slot = new->instance.slots; + slotf = set_slot; + return(TRUE); + } + else { + x = DEREF(x); + goto RETRY; + } + default: return(FALSE); + } +} + +@(defun get_instance (x class arity) +@ + @(return `get_instance(x, class, fix(arity))?Ct:Cnil`) +@) + + +/* -------------------- Unify Instructions -------------------- */ + +#define UNIFY_LOCATIVE(x, y, L) {object *p = &DEREF(x); \ + if (*p == OBJNULL) { \ + BIND(*p, y); return(TRUE); } \ + else { x = *p; goto L;}} +/* +#define UNIFY_LOCATIVE(x, y, L) {if (UNBOUNDP(x)) { \ + BIND(DEREF(x), y); return(TRUE); } \ + else { x = DEREF(x); goto L;}} +*/ + +bool +unify(object x, object y) +{ + /* NOTE: x <- y */ + + L: switch (type_of(x)) { + + case t_locative: UNIFY_LOCATIVE(x, y, L); + + case t_cons: + L1: switch (type_of(y)) { + + case t_cons: return(unify(CAR(x), CAR(y)) && + unify(CDR(x), CDR(y))); + + case t_locative: UNIFY_LOCATIVE(y, x, L1); + + default: return(FALSE); + } + + case t_instance: + L2: switch (type_of(y)) { + + case t_instance: + if (CLASS_OF(x) == CLASS_OF(y)) { + int l = x->instance.length; int i; + object *slotx = x->instance.slots; + object *sloty = y->instance.slots; + for (i = 0; i < l; i++) { + if (!unify(*slotx++, *sloty++)) + return(FALSE); + } + return(TRUE); + } else + return(FALSE); + + case t_locative: UNIFY_LOCATIVE(y, x, L2); + + default: return(FALSE); + } + + default: + L3: if (LOCATIVEP(y)) + UNIFY_LOCATIVE(y, x, L3) + else if (equal(x,y)) + return(TRUE); + else + return(FALSE); + } +} + +/* Internal function. One should use unify_variable, which always returns T */ + +@(defun unify_slot () +@ + @(return `(object)unify_slot`) +@) + + +@(defun unify_value (loc) + object x; +@ + x = (object)unify_value(loc); + @(return `(x == Cnil || x)?Ct:Cnil`) +@) + +@(defun unify_constant (c) + object x; +@ + x = (object)unify_constant(c); + @(return `(x == Cnil || x)?Ct:Cnil`) +@) + +@(defun unify_nil () + object x; +@ + x = (object)unify_nil; + @(return `(x == Cnil || x)?Ct:Cnil`) +@) + +/* -------------------- Test Functions -------------------- */ + +@(defun make_locative (&optional (n 0)) +@ + @(return `MAKE_LOCATIVE(fix(n))`) +@) + +@(defun locativep (obje) +@ + @(return `LOCATIVEP(obje)?Ct:Cnil`) +@) + +@(defun unboundp (loc) +@ + @(return `UNBOUNDP(loc)?Ct:Cnil`) +@) + +@(defun dereference (x) + extern object Slocative; +@ + while (type_of(x) != t_locative) + x = wrong_type_argument(Slocative, x); + @(return `DEREF(x)`) +@) + +@(defun make_variable (name) +@ + @(return `CONS(name, OBJNULL)`) +@) + +/* (defmacro unify-variable (v) `(progn (setq ,v (si:unify-slot)) t) */ + +object Ssetq, Sunify_slot; + +@(defun unify_variable (object var) +@ + @(return list(3, Sprogn, + list(3, Ssetq, CADR(var), + CONS(Sunify_slot, Cnil)), + Ct)) +@) + +#define make_si_macro(name, cfun) \ + {object x = make_si_ordinary(name); \ + SYM_FUN(x) = make_cfun(cfun, Cnil, NULL); \ + x->symbol.mflag = TRUE; \ + } + +void +init_unify(void) +{ + make_si_macro("UNIFY-VARIABLE", Lunify_variable); +} diff --git a/src/c/unixfsys.d b/src/c/unixfsys.d new file mode 100644 index 000000000..c4fdde793 --- /dev/null +++ b/src/c/unixfsys.d @@ -0,0 +1,573 @@ +/* + unixfsys.c -- Unix file system interface. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" +#include +#include +#include +#include +#include +#ifdef BSD +#include +#else +#include "" +#endif + +cl_object Klist_all; + +/* + * string_to_pathanme, to be used when s is a real pathname + */ +cl_object +string_to_pathname(char *s) +{ + cl_index e; + return parse_namestring(s, 0, strlen(s), &e, Cnil); +} + +/* + * Finds current directory by using getcwd() with an adjustable + * string which grows until it can host the whole path. + */ +static cl_object +current_dir(void) { + cl_object output; + const char *ok; + extern char *getcwd(char *, size_t); + cl_index size = 128; + + do { + output = alloc_adjustable_string(size); + ok = getcwd(output->string.self, size); + size += 256; + } while(ok == NULL); + size = strlen(output->string.self); + if ((size + 1 /* / */ + 1 /* 0 */) >= output->string.dim) { + /* Too large to host the trailing '/' */ + cl_object other = alloc_adjustable_string(size+2); + strcpy(other->string.self, output->string.self); + output = other; + } + output->string.self[size++] = '/'; + output->string.self[size] = 0; + output->string.fillp = size; + return output; +} + +/* + * Using a certain path, guess the type of the object it points to. + */ + +enum file_system_type { + FILE_DOES_NOT_EXIST = 0, + FILE_REGULAR = 1, + FILE_DIRECTORY = 2, + FILE_OTHER = 3 +}; + +static int +get_file_system_type(const char *namestring) { + struct stat buf; + + if (stat(namestring, &buf) < 0) + return FILE_DOES_NOT_EXIST; + if (S_ISREG(buf.st_mode)) + return FILE_REGULAR; + if (S_ISDIR(buf.st_mode)) + return FILE_DIRECTORY; + return FILE_OTHER; +} + + +/* + * Search the actual name of the directory of a pathname, + * going through links if they exist. Default is + * current directory + */ +static cl_object +error_no_dir(cl_object pathname) { + FEerror("truedirectory: does not exist or cannot be accessed",1,pathname); + return OBJNULL; +} + +cl_object +truedirectory(cl_object pathname) +{ + cl_object directory; + + directory = current_dir(); + if (pathname->pathname.directory != Cnil) { + cl_object dir = pathname->pathname.directory; + if (CAR(dir) == Kabsolute) + chdir("/"); + for (dir=CDR(dir); !Null(dir); dir=CDR(dir)) { + cl_object name = CAR(dir); + if (name == Kup) { + if (chdir("..") < 0) + return error_no_dir(pathname); + } else if (type_of(name) == t_string) { + if (chdir(name->string.self) < 0) + return error_no_dir(pathname); + } else + FEerror("truename: ~A not allowed in filename",1,name); + } + dir = current_dir(); + chdir(directory->string.self); + directory = dir; + } + return directory; +} + +cl_object +truename(cl_object pathname) +{ + cl_object directory; + cl_object truefilename; + + pathname = coerce_to_file_pathname(pathname); + + /* We are looking for a file! */ + if (pathname->pathname.name == Cnil) + FEerror("truename: no file name supplied",0); + + /* Wildcards are not allowed */ + if (pathname->pathname.name == Kwild || + pathname->pathname.type == Kwild) + FEerror("truename: :wild not allowed in filename",0); + + directory = truedirectory(pathname); + + /* Compose a whole pathname by adding the + file name and the file type */ + if (Null(pathname->pathname.type)) + truefilename = siLstring_concatenate(2, directory, pathname->pathname.name); + else { + truefilename = siLstring_concatenate(4, directory, + pathname->pathname.name, + make_simple_string("."), + pathname->pathname.type); + } + + /* Finally check that the object exists and it is + either a file or a device. (FIXME! Should we + reject devices, pipes, etc?) */ + switch (get_file_system_type(truefilename->string.self)) { + case FILE_DOES_NOT_EXIST: + FEerror("truename: file does not exist or cannot be accessed",1,pathname); + return OBJNULL; + case FILE_DIRECTORY: + FEerror("truename: ~A is a directory", 1, truefilename); + return OBJNULL; + default: + return coerce_to_pathname(truefilename); + } +} + +bool +file_exists(cl_object file) +{ + struct stat filestatus; + + /* INV: If input is a string, it assumes it is a valid file name */ + if (type_of(file) != t_string) + file = coerce_to_filename(file); + if (stat(file->string.self, &filestatus) >= 0) + return(TRUE); + else + return(FALSE); +} + +FILE * +backup_fopen(char *filename, char *option) +{ + char backupfilename[MAXPATHLEN]; + char command[MAXPATHLEN * 2]; + + strcat(strcpy(backupfilename, filename), ".BAK"); + sprintf(command, "mv %s %s", filename, backupfilename); + system(command); + return(fopen(filename, option)); +} + +int +file_len(FILE *fp) +{ + struct stat filestatus; + + fstat(fileno(fp), &filestatus); + return(filestatus.st_size); +} + +@(defun truename (file) +@ + /* INV: truename() checks type of file */ + @(return truename(file)) +@) + +@(defun rename_file (old new) + cl_object filename, newfilename, old_truename, new_truename; +@ + /* INV: coerce_to_file_pathname() checks types */ + old = coerce_to_file_pathname(old); + new = coerce_to_file_pathname(new); + new = merge_pathnames(new, old, Cnil); + old_truename = truename(old); + filename = coerce_to_filename(old); + newfilename = coerce_to_filename(new); + if (rename(filename->string.self, newfilename->string.self) < 0) + FEerror("Cannot rename the file ~S to ~S.", 2, old, new); + new_truename = truename(new); + @(return new old_truename new_truename) +@) + +@(defun delete_file (file) + cl_object filename; +@ + /* INV: coerce_to_filename() checks types */ + filename = coerce_to_filename(file); + if (unlink(filename->string.self) < 0) + FEerror("Cannot delete the file ~S.", 1, file); + @(return Ct) +@) + +@(defun probe_file (file) +@ + /* INV: file_exists() and truename() check types */ + @(return (file_exists(file)? truename(file) : Cnil)) +@) + +@(defun file_write_date (file) + cl_object filename, time; + struct stat filestatus; +@ + /* INV: coerce_to_filename() checks types */ + filename = coerce_to_filename(file); + if (stat(filename->string.self, &filestatus) < 0) + time = Cnil; + else + time = UTC_time_to_universal_time(filestatus.st_mtime); + @(return time) +@) + +@(defun file_author (file) + cl_object filename; + struct stat filestatus; + struct passwd *pwent; +#ifndef __STDC__ + extern struct passwd *getpwuid(uid_t); +#endif +@ + /* INV: coerce_to_filename() checks types */ + filename = coerce_to_filename(file); + if (stat(filename->string.self, &filestatus) < 0) + FEerror("Cannot get the file status of ~S.", 1, file); + pwent = getpwuid(filestatus.st_uid); + @(return make_string_copy(pwent->pw_name)) +@) + +const char * +expand_pathname(const char *name) +{ + const char *path, *p; + static char pathname[255], *pn; + + if (IS_DIR_SEPARATOR(name[0])) return(name); + if ((path = getenv("PATH")) == NULL) error("No PATH in environment"); + p = path; + pn = pathname; + do { + if ((*p == '\0') || (*p == PATH_SEPARATOR)) { + if (pn != pathname) *pn++ = DIR_SEPARATOR; /* on SYSV . is empty */ +LAST: strcpy(pn, name); + if (access(pathname, X_OK) == 0) + return (pathname); + pn = pathname; + if (p[0] == PATH_SEPARATOR && p[1] == '\0') { /* last entry is empty */ + p++; + goto LAST; + } + } + else + *pn++ = *p; + } while (*p++ != '\0'); + return(name); /* should never occur */ +} + +cl_object +homedir_pathname(cl_object user) +{ + cl_index i; + char *p, filename[MAXPATHLEN]; + struct passwd *pwent = NULL; +#ifndef __STDC__ + extern struct passwd *getpwuid(uid_t), *getpwnam(); +#endif + + if (Null(user)) + pwent = getpwuid(getuid()); + else { + user = coerce_to_string(user); + p = user->string.self; + i = user->string.fillp; + if (i > 0 && *p == '~') { + p++; + i--; + } + if (i == 0) + pwent = getpwuid(getuid()); + else { + strncpy(filename, p, i); + filename[i] = '\0'; + pwent = getpwnam(filename); + } + } + if (pwent == NULL) + FEerror("Unknown user ~S.", 1, user); + strcpy(filename, pwent->pw_dir); + i = strlen(filename); + if (i == 0 || filename[i-1] != '/') { + filename[i++] = '/'; + filename[i] = '\0'; + } + return string_to_pathname(filename); +} + +@(defun user_homedir_pathname (&optional host) + cl_object pathname; +@ + /* Ignore optional host argument. */ +#ifdef MSDOS + { extern char *getenv(); + char *h = getenv("HOME"); + pathname = (h == NULL)? make_simple_string("/") + : make_string_copy(h); + } +#else + pathname = homedir_pathname(Cnil); +#endif MSDOS + @(return pathname) +@) + +/* + * Take two C strings and check if the first one matches + * against the pattern given by the second one. The pattern + * is that of a Unix shell except for brackets and curly + * braces + */ +static bool +string_match(const char *s, const char *p) { + const char *next; + while (*s) { + switch (*p) { + case '*': + /* Match any group of characters */ + next = p+1; + if (*next != '?') { + if (*next == '\\') + next++; + while (*s && *s != *next) s++; + } + if (string_match(s,next)) + return TRUE; + /* starts back from the '*' */ + if (!*s) + return FALSE; + s++; + break; + case '?': + /* Match any character */ + s++, p++; + break; + case '\\': + /* Interpret a pattern character literally. + Trailing slash is interpreted as a slash. */ + if (p[1]) p++; + if (*s != *p) + return FALSE; + s++, p++; + break; + default: + if (*s != *p) + return FALSE; + s++, p++; + break; + } + } + while (*p == '*') + p++; + return (*p == 0); +} + +@(defun si::string_match (s1 s2) +@ + assert_type_string(s1); + assert_type_string(s2); + @(return (string_match(s1->string.self, s2->string.self) ? Ct : Cnil)) +@) + +static cl_object +actual_directory(cl_object namestring, cl_object mask, bool all) +{ + cl_object ret = Cnil; + cl_object saved_dir = current_dir(); + cl_object *directory = &ret; + cl_object dir_path = coerce_to_file_pathname(namestring); + enum file_system_type t; +#if defined(BSD) +/* + * version by Brian Spilsbury , using opendir() + * arranged by Juan Jose Garcia Ripoll to understand masks + */ + DIR *dir; + struct dirent *entry; + + if (chdir(namestring->string.self) < 0) { + chdir(saved_dir->string.self); + FEerror("directory: cannot access ~A",1,namestring); + } + dir = opendir("."); + if (dir == NULL) { + chdir(saved_dir->string.self); + FEerror("Can't open the directory ~S.", 1, dir); + } + + while ((entry = readdir(dir))) { + t = get_file_system_type(entry->d_name); + if ((all || t == FILE_REGULAR) && + string_match(entry->d_name, mask->string.self)) + { + cl_index e = strlen(entry->d_name); + cl_object file = parse_namestring(entry->d_name, 0, e, &e, Cnil); + file = merge_pathnames(dir_path, file,Cnil); + *directory = CONS(file, Cnil); + directory = &CDR(*directory); + } + } + closedir(dir); +#endif +#if defined(SYSV) + FILE *fp; + char iobuffer[BUFSIZ]; + DIRECTORY dir; + + if (chdir(namestring->string.self) < 0) { + chdir(saved_dir->string.self); + FEerror("directory: cannot access ~A",1,namestring); + } + fp = fopen(".", OPEN_R); + if (fp == NULL) { + chdir(saved_dir->string.self); + FEerror("Can't open the directory ~S.", 1, dir); + } + + setbuf(fp, iobuffer); + /* FIXME! What are these three lines for? */ + fread(&dir, sizeof(DIRECTORY), 1, fp); + fread(&dir, sizeof(DIRECTORY), 1, fp); + for (;;) { + if (fread(&dir, sizeof(DIRECTORY), 1, fp) <= 0) + break; + if (dir.d_ino == 0) + continue; + t = get_file_system_type(dir.d_name); + if ((all || t == FILE_REGULAR) && + string_match(dir.d_name, mask->string.self)) + { + int e = strlen(dir.d_name); + cl_object file = parse_namestring(dir.d_name, 0, e, &e); + file = merge_pathnames(dir_path, file,Cnil); + *directory = CONS(file, Cnil); + directory = &CDR(*directory); + } + } + fclose(fp); +#endif + chdir(saved_dir->string.self); + return ret; +} + +@(defun directory (&optional (filemask OBJNULL) + (kall OBJNULL)) + cl_object directory; + cl_object name, type, mask; + bool all = FALSE; +@ + /* Without arguments, it justs lists all files in + current directory */ + if (filemask == OBJNULL) { + directory = current_dir(); + mask = make_simple_string("*"); + goto DO_MATCH; + } + + if (kall == Klist_all) + all = TRUE; + else if (kall != OBJNULL) + FEwrong_type_argument(Skeyword, kall); + + /* INV: coerce_to_file_pathname() checks types */ + filemask = coerce_to_file_pathname(filemask); + name = filemask->pathname.name; + type = filemask->pathname.type; + + directory = truedirectory(filemask); + + if (name == Kwild) + name = make_simple_string("*"); + else if (name == Cnil) { + if (type == Cnil) + name = make_simple_string("*"); + else + name = null_string; + } + + if (type == Cnil) + mask = name; + else { + cl_object dot = make_simple_string("."); + if (type == Kwild) + type = make_simple_string("*"); + mask = siLstring_concatenate(3, name, dot, type); + } + DO_MATCH: + @(return actual_directory(directory, mask, all)) +@) + +@(defun si::chdir (directory) + cl_object filename, previous; +@ + /* INV: coerce_to_filename() checks types */ + filename = coerce_to_filename(directory); + previous = current_dir(); + if (chdir(filename->string.self) < 0) + FEerror("Can't change the current directory to ~S.", + 1, directory); + @(return previous) +@) + +#ifdef sun4sol2 +/* These functions can't be used with static linking on Solaris */ +struct passwd * +getpwnam(const char *name) +{ + FEerror("~~ expansion not supported on Solaris.", 0); +} +struct passwd * +getpwuid(uid_t uid) +{ + FEerror("ECL can't use getpwuid on Solaris.", 0); +} +#endif diff --git a/src/c/unixint.d b/src/c/unixint.d new file mode 100644 index 000000000..d01fd0bf0 --- /dev/null +++ b/src/c/unixint.d @@ -0,0 +1,175 @@ +/* + unixint.c -- Unix interrupt interface. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + + +#include "ecls.h" +#include + +/******************************* EXPORTS ******************************/ + +int interrupt_enable; /* console interupt enable */ +int interrupt_flag; /* console interupt flag */ + +/******************************* ------- ******************************/ + +static cl_object SVinterrupt_enable; + +#ifndef THREADS + +void +sigalrm(void) +{ + if (interrupt_flag) { + interrupt_flag = FALSE; + terminal_interrupt(TRUE); + } +} + +void +sigint(void) +{ + if (!interrupt_enable || interrupt_flag) { + if (!interrupt_enable) { + fprintf(stdout, "\n;;;Interrupt delayed.\n"); fflush(stdout); + interrupt_flag = TRUE; + } + signal(SIGINT, sigint); + return; + } + if (symbol_value(SVinterrupt_enable) == Cnil) { + SYM_VAL(SVinterrupt_enable) = Ct; + signal(SIGINT, sigint); + return; + } +#ifdef __GO32__ + if (interrupt_flag) + sigalrm(); +#endif + interrupt_flag = TRUE; + signal(SIGALRM, sigalrm); + alarm(1); + signal(SIGINT, sigint); +} + +#else /* THREADS */ + +extern int critical_level; +bool scheduler_interrupted = FALSE; +int scheduler_interruption = 0; + +void +sigint() +{ +#ifdef SYSV + signal(SIGINT, sigint); +#endif + if (critical_level > 0) { + scheduler_interrupted = TRUE; + scheduler_interruption = ERROR_INT; + return; + } + + if (symbol_value(SVinterrupt_enable) == Cnil) { + SVinterrupt_enable->symbol.dbind = Ct; + return; + } + + terminal_interrupt(TRUE); +} + +#endif /*THREADS */ + +void +sigfpe(void) +{ + signal(SIGFPE, sigfpe); + FEerror("Floating-point exception.", 0); +} + +#ifdef unix +void +signal_catcher(int sig, int code, int scp) +{ + char str[64]; + + if (!interrupt_enable) { + sprintf(str, "signal %d caught (during GC)", sig); + error(str); + } + else if (sig == SIGSEGV) + FEerror("Segmentation violation.~%\ +Wrong type argument to a compiled function.", 0); + else { + printf("System error. Trying to recover ...\n"); + fflush(stdout); + FEerror("Signal ~D caught.~%\ +The internal memory may be broken.~%\ +You should check the signal and exit from Lisp.", 1, + MAKE_FIXNUM(sig)); + } +} + +@(defun si::catch_bad_signals () +@ + signal(SIGILL, signal_catcher); + signal(SIGBUS, signal_catcher); + signal(SIGSEGV, signal_catcher); +#ifdef SIGIOT + signal(SIGIOT, signal_catcher); +#endif +#ifdef SIGEMT + signal(SIGEMT, signal_catcher); +#endif +#ifdef SIGSYS + signal(SIGSYS, signal_catcher); +#endif + @(return Ct) +@) + +@(defun si::uncatch_bad_signals () +@ + signal(SIGILL, SIG_DFL); + signal(SIGBUS, SIG_DFL); + signal(SIGSEGV, SIG_DFL); +#ifdef SIGIOT + signal(SIGIOT, SIG_DFL); +#endif +#ifdef SIGEMT + signal(SIGEMT, SIG_DFL); +#endif +#ifdef SIGSYS + signal(SIGSYS, SIG_DFL); +#endif + @(return Ct) +@) +#endif unix + +void +enable_interrupt(void) +{ + interrupt_enable = TRUE; + signal(SIGFPE, sigfpe); + signal(SIGINT, sigint); +#ifdef __EMX__ + signal(SIGBREAK, sigint); +#endif +} + +void +init_interrupt(void) +{ + SVinterrupt_enable = make_si_special("*INTERRUPT-ENABLE*", Ct); +} diff --git a/src/c/unixsys.d b/src/c/unixsys.d new file mode 100644 index 000000000..9c300ef66 --- /dev/null +++ b/src/c/unixsys.d @@ -0,0 +1,115 @@ +/* + unixsys.s -- Unix shell interface. +*/ +/* + Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. + Copyright (c) 1990, Giuseppe Attardi. + Copyright (c) 2001, Juan Jose Garcia Ripoll. + + ECLS is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 '../Copyright' for full details. +*/ + +#include "ecls.h" + +#if !defined(__stdlib_h) && !defined(_STDLIB_H_) && !defined(__STDLIB_H__) && !defined(_STDLIB_H) +#include +int +system(const char *command) +{ + char buf[4]; + extern sigint(); + + signal(SIGINT, SIG_IGN); + write(4, command, strlen(command)+1); + read(5, buf, 1); + signal(SIGINT, sigint); + return(buf[0]<<8); +} +#endif __STDLIB_H__ + +#if defined(__FreeBSD__) || defined(__NetBSD__) + +/* due to the calls to realloc in system.c/exec.c (memory which hasn't been +malloc'ed can't be realloced in ecl) we have to patch this a bit. +We use execv and supply the arg list, so execl doesn't have to realloc. CvdL */ + +#include +#include +#include +#include +#include +#include +#include + +int +system(command) + const char *command; +{ + union wait pstat; + pid_t pid; + int omask; + sig_t intsave, quitsave; + + if (!command) /* just checking... */ + return(1); + + omask = sigblock(sigmask(SIGCHLD)); + switch(pid = vfork()) { + case -1: /* error */ + (void)sigsetmask(omask); + pstat.w_status = 0; + pstat.w_retcode = 127; + return(pstat.w_status); + case 0: { /* child */ + const char *args[] = { "sh", "-c", command, (char *)NULL }; + (void)sigsetmask(omask); + execv(_PATH_BSHELL, args); + _exit(127); + } + } + intsave = signal(SIGINT, SIG_IGN); + quitsave = signal(SIGQUIT, SIG_IGN); + pid = waitpid(pid, (int *)&pstat, 0); + (void)sigsetmask(omask); + (void)signal(SIGINT, intsave); + (void)signal(SIGQUIT, quitsave); + return(pid == -1 ? -1 : pstat.w_status); +} +#endif + +@(defun si::system (cmd) +@ + assert_type_string(cmd); + /* FIXME! Are there any limits for system()? */ + /* if (cmd->string.fillp >= 1024) + FEerror("Too long command line: ~S.", 1, cmd);*/ + /* FIXME! This is a non portable way of getting the exit code */ + @(return MAKE_FIXNUM(system(cmd->string.self) >> 8)) +@) + +@(defun si::open_pipe (cmd) + FILE *ptr; + cl_object stream; +@ + assert_type_string(cmd); + + if ((ptr = popen(cmd->string.self, OPEN_R)) == NULL) + @(return Cnil) + stream = alloc_object(t_stream); + stream->stream.mode = smm_input; + stream->stream.file = ptr; + stream->stream.object0 = Sbase_char; + stream->stream.object1 = cmd; + stream->stream.int0 = stream->stream.int1 = 0; +#if !defined(GBC_BOEHM) + /* FIXME! This is not portable */ + ptr->_IO_buf_base = NULL; + setbuf(ptr, stream->stream.buffer = alloc_atomic(BUFSIZ)); +#endif + @(return stream) +@) diff --git a/src/clos/boot.lsp b/src/clos/boot.lsp new file mode 100644 index 000000000..8280d0956 --- /dev/null +++ b/src/clos/boot.lsp @@ -0,0 +1,142 @@ +;;;; Copyright (c) 1992, Giuseppe Attardi. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Library 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 '../Copyright' for full details. + +(in-package "CLOS") + +;;; ---------------------------------------------------------------------- +;;; BOOT + +(defun boot () + (let ((class (find-class 'class)) + (built-in (find-class 'built-in))) + + ;; class CLASS -------- + (setf (class-slots class) + (parse-slots '((NAME :INITARG :NAME :INITFORM NIL) + (SUPERIORS :INITARG :DIRECT-SUPERCLASSES) + (INFERIORS :INITFORM NIL) + (SLOTS :INITARG :SLOTS)))) + + (defmethod OPTIMIZE-SLOT-VALUE ((class class) form) form) + + (defmethod OPTIMIZE-SET-SLOT-VALUE ((class class) form) form) + + (defmethod make-instance ((class class) &rest initargs) + (let ((instance (allocate-instance class))) + (apply #'initialize-instance instance initargs) + instance)) + + (defmethod initialize-instance ((class class) + &rest initargs + &key direct-superclasses + &allow-other-keys) + + (call-next-method) ; from class T + + ;; default inheritance + (unless direct-superclasses + (setf (class-superiors class) + (class-default-direct-superclasses class direct-superclasses))) + + ;; if the class has a name register it in hash table + (when (si:sl-boundp (class-name class)) + (setf (find-class (class-name class)) class)) + (dolist (s (class-superiors class)) ; inheritance lattice + (push class (class-inferiors s))) + class) + + (defmethod class-default-direct-superclasses ((class class) + supplied-superclasses) + (or supplied-superclasses + (list (find-class 't)))) + + ;; class BUILT-IN -------- + (setf (class-slots built-in) + (parse-slots '((NAME :INITARG :NAME :INITFORM NIL) + (SUPERIORS :INITARG :DIRECT-SUPERCLASSES) + (INFERIORS :INITFORM NIL) + (SLOTS :INITARG :SLOTS)))) + + (defmethod slot-value ((self built-in) slot) + (let ((position (position slot (class-slots (si:instance-class self)) + :key #'slotd-name))) + (if position + (si:instance-ref self position) + (slot-missing (si:instance-class self) self slot 'slot-value)))) + + (defmethod make-instance ((class built-in) &rest initargs) + (declare (ignore initargs)) + (error "The built-in class (~A) cannot be instantiated" class)) + + (defmethod initialize-instance ((class built-in) + &rest initargs &key &allow-other-keys) + + (call-next-method) ; from class T + + ;; if the class has a name register it in hash table + (when (si:sl-boundp (class-name class)) + (setf (find-class (class-name class)) class)) + + (dolist (s (class-superiors class)) ; inheritance lattice + (push class (class-inferiors s))) + class) + + (defmethod print-object ((class built-in) stream) + (print-unreadable-object + (class stream) + (format stream "The ~A ~A" (class-name (si:instance-class class)) + (class-name class))) + class) + + ;; class T -------- + (defmethod initialize-instance ((instance T) + &rest initargs &key &allow-other-keys) + (let ((class-slots (class-slots (si:instance-class instance)))) + ;; initialize from initforms + (do ((scan class-slots (cdr scan)) + (i 0 (1+ i))) + ((null scan)) + (when (and (not (si:sl-boundp + (si:instance-ref instance i))) + (not (eq (slotd-initform (first scan)) + 'INITFORM-UNSUPPLIED))) + (si:instance-set instance i + (eval (slotd-initform (first scan)))))) + + ;; initialize from initargs + (do* ((name-loc initargs (cddr name-loc)) + (name (first name-loc) (first name-loc))) + ((null name-loc)) + ;; scan the class-slots to fill them with the initargs + (do ((scan-slot class-slots (cdr scan-slot)) + (index 0 (1+ index))) + ((null scan-slot) ()) + (declare (fixnum index)) + ;; if the initarg is associated with a slot + (when (member name (slotd-initargs (first scan-slot))) + ;; fill the slot + (setf (si:instance-ref instance index) + (second name-loc))) + ;; go on scanning the slots because a single initarg + ;; can initialize more than one slot + ))) + instance) + + (defmethod slot-missing ((class t) object slot-name operation + &optional new-value) + (declare (ignore operation new-value)) + (error "~A is not a slot of ~A" slot-name object)) + + (defmethod slot-unbound ((class t) object slot-name) + (error "the slot ~A of ~A is unbound" slot-name object)) + )) + +(boot) + +;;; ---------------------------------------------------------------------- diff --git a/src/clos/builtin.lsp b/src/clos/builtin.lsp new file mode 100644 index 000000000..914795fee --- /dev/null +++ b/src/clos/builtin.lsp @@ -0,0 +1,184 @@ +;;;; Copyright (c) 1992, Giuseppe Attardi. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Library 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 '../Copyright' for full details. + +(in-package "CLOS") + +;;; ---------------------------------------------------------------------- +;;; Built-in classes +;;; ---------------------------------------------------------------------- + +;;; ---------------------------------------------------------------------- +;;; Predefined Common Lisp Classes + +;(defclass t (object) () (:metaclass built-in)) + +(defclass array (t) () (:metaclass built-in)) +(defclass sequence (t) () (:metaclass built-in)) + (defclass list (sequence) () (:metaclass built-in)) + (defclass cons (list) () (:metaclass built-in)) + (defclass string (array sequence) () (:metaclass built-in)) + (defclass vector (array sequence) () (:metaclass built-in)) + (defclass bit-vector (vector) () (:metaclass built-in)) + +(defclass character (t) () (:metaclass built-in)) + +(defclass number (t) () (:metaclass built-in)) + (defclass complex (number) () (:metaclass built-in)) + (defclass float (number) () (:metaclass built-in)) + (defclass rational (number) () (:metaclass built-in)) + (defclass integer (rational) () (:metaclass built-in)) + (defclass ratio (rational) () (:metaclass built-in)) + +(defclass symbol (t) () (:metaclass built-in)) + (defclass null (symbol list) () (:metaclass built-in)) + (defclass keyword (symbol) () (:metaclass built-in)) + +(defclass pathname (t) () (:metaclass built-in)) + (defclass logical-pathname (pathname) () (:metaclass built-in)) + +;;; Now we protect classes from redefinition: +(defun setf-find-class (name new-value) + (cond + ((member name '(T NIL NULL SYMBOL KEYWORD ATOM CONS LIST SEQUENCE + NUMBER INTEGER BIGNUM RATIONAL RATIO FLOAT + SHORT-FLOAT SINGLE-FLOAT DOUBLE-FLOAT LONG-FLOAT COMPLEX + CHARACTER STANDARD-CHAR BASE-CHAR EXTENDED-CHAR + PACKAGE STREAM PATHNAME READTABLE HASH-TABLE RANDOM-STATE + STRUCTURE ARRAY SIMPLE-ARRAY FUNCTION COMPILED-FUNCTION + LOGICAL-PATHNAME)) + (error "The class associated to the CL specifier ~S cannot be changed." + name)) + ((member name '(CLASS BUILT-IN) :test #'eq) + (error "The kernel CLOS class ~S cannot be changed." name)) + ((classp new-value) + (setf (gethash name si:*class-name-hash-table*) new-value)) + ((null new-value) (remhash name si:*class-name-hash-table*)) + (t (error "~A is not a class." new-value)))) + +;;; ---------------------------------------------------------------------- +;;; Methods + +(defmethod make-instance ((class-name symbol) &rest initargs) + (apply #'make-instance (find-class class-name) initargs)) + +(defmethod change-class ((instance t) (new-class symbol)) + (funcall #'change-class instance (find-class new-class))) + +;;; ---------------------------------------------------------------------- +;;; Structures +;;; ---------------------------------------------------------------------- + +(defun create-structure-class (name + superclasses-names + direct-slots all-slots + default-initargs documentation) + (declare (ignore class-slots default-initargs documentation)) + (dolist (slot all-slots) + (unless (eq :INSTANCE (slotd-allocation slot)) + (error "The structure class ~S can't have shared slots" name))) + (let* ((metaclass (find-class 'STRUCTURE-CLASS)) + (existing (find-class name nil)) + (superclasses (mapcar #'find-class superclasses-names)) + (cpl (compute-class-precedence-list name superclasses))) + + (flet ((unchanged-class () + (and existing + (eq metaclass (si:instance-class existing)) + (equal (or superclasses-names '(STRUCTURE-OBJECT)) + ;; i.e. class-default-direct-superclasses + (mapcar #'(lambda (x) (class-name x)) + (class-superiors existing))) + (equal all-slots (slot-value existing 'SLOTS)) + (prog2 (setf (slot-value existing 'DOCUMENTATION) + documentation) + t)))) + + (if (unchanged-class) + existing + (make-instance metaclass + :name name + :direct-superclasses superclasses + :slots all-slots + :class-precedence-list cpl))))) + +;;; the method to make instances of structure-class +#+nil +(defmethod make-instance ((class structure-metaclass) &rest initargs) + (let ((instance (allocate-instance class))) + (apply #'initialize-instance instance initargs) + instance)) + +;;; ----------------------------------------------------------------------- +;;; Structure-class + +(defclass structure-class (class) + ;; class-precedence-list must be in the same position as in standard-class + ((precedence-list :initarg :class-precedence-list) + slot-descriptions initial-offset defstruct-form constructors documentation + copier predicate print-function) + (:metaclass class)) + +;;; structure-classes cannot be instantiated +(defmethod make-instance ((class structure-class) &rest initargs) + (declare (ignore initargs)) + (error "The structure-class (~A) cannot be instantiated" class)) + +;;; the method to initialize the instances of structure-class +(defmethod initialize-instance ((class structure-class) + &rest initargs &key &allow-other-keys) + (call-next-method) ; from class T + + ;; if the class has a name register it in hash table + (when (system:sl-boundp (class-name class)) + (setf (find-class (class-name class)) class)) + + (dolist (s (class-superiors class)) ; inheritance lattice + (push class (class-inferiors s))) + (push class (slot-value class 'PRECEDENCE-LIST)) ;; add itself in cpl + class) + +;;; ---------------------------------------------------------------------- +;;; Structure-object +;;; ---------------------------------------------------------------------- + +;;; Structure-object has no slots and inherits only from t: +;;; (defclass structure-object (t) ()) + +(eval-when + (compile load eval) + (make-instance (find-class 'STANDARD-CLASS) + :name 'STRUCTURE-OBJECT + :direct-superclasses (list (find-class 't)) + :slots () + :class-precedence-list () + :slot-index-table () + :direct-slots () + :default-initargs () + :documentation "The root of inheritance for structures")) + +(defmethod print-object ((obj structure-object) stream) + (let* ((class (si:instance-class obj)) + (slotds (class-slots class))) + (princ "#S(" stream) + (prin1 (class-name class) stream) + (do ((scan slotds (cdr scan)) + (i 0 (1+ i)) + (sv)) + ((null scan)) + (declare (fixnum i)) + (setq sv (si:instance-ref obj i)) + (princ " " stream) + (prin1 (slotd-name (car scan)) stream) + (princ " " stream) + (prin1 sv stream) + ) + (princ ")" stream) + obj)) + +;;; ---------------------------------------------------------------------- diff --git a/src/clos/change.lsp b/src/clos/change.lsp new file mode 100644 index 000000000..731ce6c20 --- /dev/null +++ b/src/clos/change.lsp @@ -0,0 +1,176 @@ +;;;; Copyright (c) 1992, Giuseppe Attardi. +;;;; +;;;; This program is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Library 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 '../Copyright' for full details. + +(in-package "CLOS") + +;;; The mechanism for updating classes. + +;;; ---------------------------------------------------------------------- +;;; Invalid Class +;;; ---------------------------------------------------------------------- + +(defclass invalid () ()) + +(defmethod OPTIMIZE-SLOT-VALUE ((class class) form) form) + +(defmethod OPTIMIZE-SET-SLOT-VALUE ((class class) form) form) + +(defmethod slot-value ((object invalid) slot-name) + ;; first update the instance + (update-instance object) + ;; now access the slot + (slot-value object slot-name)) + +(defmethod (setf slot-value) (val (object invalid) slot-name) + ;; first update the instance + (update-instance object) + ;; now modify the slot + (setf (slot-value object slot-name) val)) + +;;; ---------------------------------------------------------------------- + +(defmethod class-instance-slot-count ((class class)) + (let ((count 0)) + (declare (fixnum count)) + (dolist (slot (class-slots class)) + (when (eq :INSTANCE (slotd-allocation slot)) + (incf count))) + count)) + +(defun update-instance (instance) + (let* ((old-class (class-of instance)) + (new-class (slot-value old-class 'FORWARD)) + ; was saved here by redefine-class + (old-slots (class-slots old-class)) + (new-slots (class-slots new-class)) + discarded-slots + added-slots + retained-correspondance + property-list + position) + ;; dont (declare (fixnum position)) otherwise if position will fail. + (unless (equal old-slots new-slots) + (setq discarded-slots + (set-difference (mapcar #'slotd-name old-slots) + (mapcar #'slotd-name new-slots))) + ;; compute the property list + (dolist (slot-name discarded-slots) + ;; can't use slot-value or we loop + (push (cons slot-name (standard-instance-get instance slot-name)) + property-list))) + + ;; compute retained local slots and update instance: + (let ((new-i 0) + (old-i 0) + (index-table (slot-index-table old-class)) + name + old-slot) + (declare (fixnum new-i old-i)) + (dolist (new-slot new-slots) + (setq name (slotd-name new-slot) + old-slot (find name old-slots :key #'slotd-name :test #'eq)) + (if old-slot + (when (and (eq :INSTANCE (slotd-allocation new-slot)) + (eq :INSTANCE (slotd-allocation old-slot))) + (push (cons new-i (gethash name index-table)) + retained-correspondance)) + (push new-slot added-slots)) + (incf new-i)) + + (si:change-instance instance new-class + (class-instance-slot-count new-class) + (nreverse retained-correspondance))) + + ;; initialize newly added slots + (update-instance-for-redefined-class instance added-slots + discarded-slots property-list) + )) + +(defun remove-optional-slot-accessors (class) + (let ((class-name (class-name class))) + (dolist (slotd (class-slots class)) + + (dolist (accessor (slotd-accessors slotd)) + (let* ((gfun (symbol-function accessor)) + (gf-object (si:gfun-instance gfun)) + (setf-accessor (list 'setf accessor)) + (setf-gfun (symbol-function setf-accessor)) + (setf-gf-object (si:gfun-instance setf-gfun)) + found) + ;; primary reader method + (when (setq found + (find-method gf-object nil (list class-name) nil)) + (remove-method gf-object found)) + ;; before reader method + (when (setq found + (find-method gf-object ':before (list class-name) nil)) + (remove-method gf-object found)) + ;; after reader method + (when (setq found + (find-method gf-object ':after (list class-name) nil)) + (remove-method gf-object found)) + (when (null (methods gf-object)) + (fmakunbound accessor)) + ;; primary writer method + (when (setq found + (find-method setf-gf-object nil (list nil class-name) nil)) + (remove-method setf-gf-object found)) + ;; before writer method + (when (setq found + (find-method setf-gf-object ':before (list nil class-name) nil)) + (remove-method setf-gf-object found)) + ;; after writer method + (when (setq found + (find-method setf-gf-object ':after (list nil class-name) nil)) + (remove-method setf-gf-object found)) + (when (null (methods gf-object)) + (fmakunbound setf-accessor)))) + + ;; remove previous defined reader methods + (dolist (reader (slotd-readers slotd)) + (let* ((gfun (symbol-function reader)) + (gf-object (si:gfun-instance gfun)) + found) + ;; primary method + (when (setq found + (find-method gf-object nil (list class-name) nil)) + (remove-method gf-object found)) + ;; before method + (when (setq found + (find-method gf-object ':before (list class-name) nil)) + (remove-method gf-object found)) + ;; after method + (when (setq found + (find-method gf-object ':after (list class-name) nil)) + (remove-method gf-object found)) + (when (null (methods gf-object)) + (fmakunbound reader)))) + + ;; remove previous defined writer methods + (dolist (writer (slotd-writers slotd)) + (let* ((gfun (symbol-function writer)) + (gf-object (si:gfun-instance gfun)) + found) + ;; primary method + (when (setq found + (find-method gf-object nil (list class-name) nil)) + (remove-method gf-object found)) + ;; before method + (when (setq found + (find-method gf-object ':before (list class-name) nil)) + (remove-method gf-object found)) + ;; after method + (when (setq found + (find-method gf-object ':after (list class-name) nil)) + (remove-method gf-object found)) + (when (null (methods gf-object)) + (fmakunbound writer))))))) + + +;;; ---------------------------------------------------------------------- diff --git a/src/clos/cmpinit.lsp b/src/clos/cmpinit.lsp new file mode 100644 index 000000000..4dbdb29a8 --- /dev/null +++ b/src/clos/cmpinit.lsp @@ -0,0 +1,8 @@ +(defvar std-compile (symbol-function 'compile-file)) +(defun compile-file (file &key (output-file (merge-pathnames file ".o"))) + (funcall std-compile + file + :c-file t :h-file t :data-file t :system-p t + :output-file nil)) + +;(setq compiler:*cc* (concatenate 'STRING compiler:*cc* " -I../h")) diff --git a/src/clos/combin.lsp b/src/clos/combin.lsp new file mode 100644 index 000000000..a88a787d6 --- /dev/null +++ b/src/clos/combin.lsp @@ -0,0 +1,295 @@ +;;;; Copyright (c) 1992, Giuseppe Attardi. +;;;; +;;;; ECoLisp is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Library 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 '../Copyright' for full details. + +(in-package "CLOS") + +(defun get-method-qualifiers (method) (nth 1 method)) + +(defun get-method-function (method) (nth 4 method)) + +;;; They will be redefined later: +(proclaim '(notinline get-method-qualifiers get-method-function)) + + +;;; +;;; Convert an effective method form to a compiled effective method function. +;;; The strategy is to have compiled functions around which are are templates +;;; for effective method functions. Then the effective method functions we +;;; generate are closures over the particular methods in the effective method +;;; form. This strategy has the advantage that we don't have to call the +;;; compiler when we combine new methods. It also has the advantage that +;;; same shape effective methods share the same code vector. It is of course +;;; predicated on the assumption that funcalling compiled closures is fast. +;;; +;;; *effective-method-templates* is a list of effective-method template +;;; entries. Each entry is itself a list of the form: +;;; +;;; (