B ICALC: Infix Calculator for Un*x, VAX/VMS and PC/MS-DOSB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~6 Modified and made available by:, Rao Akella> Research Assistant, Colon Cancer Control Study9 University of Minnesota, Minneapolis Introduction: ~~~~~~~~~~~~JEver wanted to do a quick calculation and didn't have a calculator handy? JICALC is a simple, portable and quickly-accessible program for doing INFIXOcomputations. It is neither very sophisticated nor intended to provide enormousJflexibility. It merely provides the functionality of a simple infix pocket calculator.In the words of the Bard:; "'Tis not so deep as a well, nor so wide as a church-door;! but 'tis enough, 'twill serve." Features:~~~~~~~~F 1) Addition (+), Subtraction (-), Multiplication (*), Division (/) 2) Modulus (%), Power (^)L 3) Bitwise logical operators: bitwise AND (&), bitwise inclusive OR (|),! unary one's complement (~)H 4) 20 Math/Trigonometric functions: sin, cos, tan, asin, acos, atan,@ sinh, cosh, tanh, exp (exponentiation), ln (natural log),D log (base 10 log), sqrt (square root), ceil (ceiling), floor,4 int/trunc (truncation), abs (absolute value),@ degtorad (degrees->radians), radtodeg (radians->degrees).L Two Date functions to convert between calendar dates and julian days:M caltojul (calendar->julian date) and jultocal (julian->calendar date).I One '?'-for-help command to display a help screen of all supported commands and functions.J 5) Temporary variables (as many as you want, with names as long as you0 want) to store intermediate computations.M 6) This is a "portable" calculator in the sense that it's not specific toK any operating system. The yacc output should be compilable by any CM compiler; this program has been tested on Unix, VAX/VMS and PC/MS-DOS,. and has required no changes to compile.L 7) This program uses the simplest of input and output formats, and is inI no way hardware dependent. So, as long as it compiles without anyI problems, there are no other requirements for it to work properly.N 8) All numbers are of the C floating-point type "double", which, accordingL to the VAX C manual, has a range of 0.29*10^-38 to 1.7*10^38, and has+ values precise to 16 decimal digits.C 9) Allows any number of expressions on a line, separated by ';'< 10) icalc can now be run either interactively (when it is? invoked without any arguments, in which case the user is> prompted for input) or in a command-line mode (when all9 expressions to be computed are passed to icalc viaB command-line "argv" arguments, in which case icalc computes@ and prints the result of each expression -- exactly as if< it had been entered interactively -- and then exits).; In the latter case, the user is supposed to delimit/& separate the expressions by ';' Availability: ~~~~~~~~~~~~)ICALC is available via Anonymous FTP from0 cccs.umn.edu (Internet Address 128.101.133.53)CJust get the file ICALC.TXT (in ASCII mode), read it and follow theinstructions contained therein.JIf you do not have FTP access, please contact me somehow with some form of>e-mail/paper-mail address, and I'll post it to you personally.Installation Instructions:~~~~~~~~~~~~~~~~~~~~~~~~~HThe installation instructions for ICALC are extremely simple, and remain4practically the same on Unix, VAX/VMS and PC/MS-DOS.MAt the end of this file, you will find a C program (it is actually the outputNfrom yacc; if you want the original yacc grammar, please ask me, and I'll postKit to you)...anyway, as I was saying, you'll find a C program at the end ofNthis file (after the "Cut here" line). Cut it out using an editor and save it$in a separate file called "icalc.c".NAll you have to do now is to compile this program using a C compiler, and thenlink it (if necessary).To be more specific:In VMS:-------1) Compile this C program using the commands:. $ DEFINE LNK$LIBRARY SYS$LIBRARY:VAXCCURSE- $ DEFINE LNK$LIBRARY_1 SYS$LIBRARY:VAXCRTLG, $ DEFINE LNK$LIBRARY_2 SYS$LIBRARY:VAXCRTL $ CC ICALC5 This should produce an object file called ICALC.OBJ.02) Then link this object file using the command: $ LINK ICALC,SYS$INPUT/OPTIONS SYS$SHARE:VAXCRTL/SHAREABLE ^Z <-- this is a Ctrl-Z $%3) Run the program using the command: $ RUN ICALC, The program will then prompt you for input.C If you want to pass the expressions you want to be computed on theC command line, you must define a global symbol (foreign command) as follows: $ ICALC :== $dev:[dir]ICALCH where "dev" and "dir" are your site-specific device and directory where ICALC.EXE resides.8 Then you can run ICALC interactively using the command: $ ICALCG Alternatively, you can run ICALC in the commmand-line mode as follows:) $ ICALC expression-1; expression-2; ... For example: $ ICALC 9+4; 9-4; 9*4; 9/4 13 5 36 2.25 $4 To exit ICALC in the interactive mode in VMS, type: Ctrl-Z, Ctrl-Y or Ctrl-C.In Unix:-------?1) Compile and link the C program "icalc.c" using the command: % cc icalc.c -lm -o icalc7 This should produce an executable file called "icalc".LNote: On some Ultrix/4.3BSD systems, not all math functions are available inJ the regular math library; they may be in the mathV library. On such5 systems, the compilation command is changed to: % cc icalc.c -lm -lmV -o icalcKSo, if you have trouble compiling icalc.c, please check your system for anynon-standard math libraries.32) Run the program interactively using the command: % icalcC To run icalc in the command-line mode, passing all the expressions- you want to be computed on the command line:, % icalc 'expression-1; expression-2; ... 'D Note: You must enclose all expressions supplied on the command line> within single quotes, because the Un*x shell interprets some? characters (like ';', '(', ')', '*', etc.) instead of passing them on to icalc. For example: % icalc '9+4; 9-4; 9*4; 9/4' 13 5 36 2.25 %. To exit icalc in Unix, type Ctrl-D or Ctrl-C. In PC/MS-DOS: ------------F The installations instructions remain basically the same: compile andH link ICALC.C. The precise syntax for compiling and linking will dependD on what compiler you're using, so I can't be any more specific thanF this. I have personally been able to get ICALC to work on a PC cloneA running MS-DOS Version 4.00, using the Microsoft QuickC Compiler; Version 2.01 and the Microsoft QuickC Linker Version 4.07.@ In PC/MS-DOS, type Ctrl-C or Ctrl-Z+Return to exit the program. Examples:~~~~~~~~JA short transcript of an ICALC session follows. This will demonstrate themajority of it's features.$ ICALCIC> 4 + 4.5 - (34/(8*3+-3)) 6.880952381 IC> -56 + 2 -54 IC> 3 ^ 2 9 IC> -3 ^ 2 -9 IC> 9 % 4 1 IC> 9.7 % 4.2 1.3IC> pi = 3.141592653589 pi = 3.141592654 3.141592654JIC> sin(PI) <- Note: Variable names are case-INsensitive.N 7.9326579347e-13 <- This is close enough to zero, don't you think?CIC> x = (y = (z = 4.5)*2)*3 <- Note: Multiple variable assignments z = 4.5 y = 9 x = 27 27 IC> ln(y) 2.197224577IC> exp(ln(y)) 9OIC> uninitialisedvariable <- Note: Uninitialised variables are automatically: 0 <- initialised to zero. IC> 1 & 2 0IC> ~3 -4 IC> 0 | 1 1IC> 9+4; 9-4; 9*4; 9/4 13 5 36 2.25)IC> ? /* help screen will be displayed */IC> sin(degtorad(90)) 1IC> radtodeg(asin(1)) 90IC> caltojul(1992, 3, 16) 149538IC> jultocal(149538) 19920316 /* yyyymmdd format */IC> caltojul(1582, 10,15)* 1 /* October 15, 1582 is julian day 1 */IC> jultocal(1) 15821015IC> floor(56.789) 560IC> int(56.789) /* trunc is an alias for int */ 56IC> floor(-56.789) -57IC> int(-56.789) -56IC> ^C$History:~~~~~~~OLet me make one thing perfectly clear. I am NOT the author of this program. IJmerely copied the yacc grammar for an infix calculator verbatim out of theN"Bison" manual (the "mfcalc" example) of the "Free Software Foundation, Inc.",Omade some cosmetic modifications to customize it to my particular taste, ran itCthrough "yacc", compiled it with a C compiler, and voila! it works.NIf you would prefer to have the original yacc grammar (icalc.y; you would needLit if you were planning to make further modifications yourself to the source.code), please ask me, and I'll post it to you.OAll comments/suggestions/problems/questions/criticism/flames/etc. most welcome.IIf there's anything at all that you don't understand or would like futherDclarified, please ask me (e-mail, paper-mail, phone, anything goes). Rao V. Akella.Research Assistant, Colon Cancer Control Study$University of Minnesota, MinneapolisAddress: E-Mail: Internet: rao@cccs.umn.edu Bitnet: rao%moose@umnacvx! Work: Home:0 212 Ontario St. S.E. 2111, 21st Ave. S.# Suite #202 #S-203 Minneapolis, MN 55414 Minneapolis, MN 55404, (612) 627-4151 (612) 339-9982N/*== Cut here == Cut here == Cut here == Cut here == Cut here == Cut here ==*/# line 1 "icalc.y"H /*== C declarations =================================================*//*P ******************************************************************************* *$ * yacc grammar : icalc.y * * version : * 2.2 of 920317 * 2.1 of 920316 * 2.0 of 911214 * 1.1 of 900816 * 1.0 of 900708 ** * author : Rao V. AkellaK * Research Assistant, Colon Cancer Control StudyA * University of Minnesota, Minneapolis *% * Address:& * E-Mail:; * Internet: rao@cccs.umn.edu< * Bitnet: rao%moose@umnacvx> * Work: Home:M * 212 Ontario St. S.E. 2111, 21st Ave. S.@ * Suite #202 #S-20P * Minneapolis, MN 55414 Minneapolis, MN 55404I * (612) 627-4151 (612) 339-9982 *# * written on : 900708 * * purpose :B * This program is a yacc grammar to parse an infix calculator. *; * date(s) modified : 920317, 920316, 911214, 900816 * * modifications :N * 920317: Fixed a bug in the definition of the "int" (truncation) function,2 * and added a new alias (trunc) for it.> * 920316: Added 1 new command and 2 new pairs of functions.J * 1) Added '?' command to display a help screen briefly describing all+ * operators and functions supported.H * 2) Added 'degtorad' and 'radtodeg' functions to convert degrees toM * radians and vice versa. This should be useful because trigonometricM * functions usually take only radian arguments (which are difficult toK * specify). Using these functions, sine of 90 degress can be easily* * computed using sin(degtorad(90)).L * 3) Added a pair of date functions 'caltojul' and 'jultocal'. This canL * typically be used to determine the difference (in days) between twoG * given dates. These functions assume the base of the Gregorian7 * calendar is October 15, 1582 (=julian day #1).L * The 'caltojul' function should be invoked as caltojul(yyyy, mm, dd)O * where yyyy is the full 4-digit year number (eg. 1992), mm is the monthL * number (rane 1-12) and dd is the day number (range 1-31). caltojulC * returns the number of days elapsed since October 15, 1582.L * The 'jultocal' function takes a julian day as input and returns theL * corresponding calendar date as an integer (in the format yyyymmdd).O * So, jultocal(1) should return 15821015, which stands for Oct 15, 1582. * 911214:O * Minor change: allow any number of expressions on a line, separated by ';'I * Major change: icalc can now be run either interactively (when it isL * invoked without any arguments, in which case the user isK * prompted for input) or in a command-line mode (when allF * expressions to be computed are passed to icalc viaO * command-line "argv" arguments, in which case icalc computesM * and prints the result of each expression -- exactly as ifI * it had been entered interactively -- and then exits).H * In the latter case, the user is supposed to delimit/3 * separate the expressions by ';' * 900816:K * Added a check to yylex() so that tolower() is invoked (to convert allO * symbol names to lower case) only if the input character is in upper case.O * Some systems have the isupper() check built into tolower(), and thereforeL * work OK even without this change, but other systems return unspecified< * results if a lower-case character is fed to tolower(). *& * invoked by : The user. * * functions called :; * init_table: Puts math/trig functions in symbol table.! * yyparse: Grammar Parser. * yyerror: Error Handler.E * yylex: Lexical Analyzer to supply tokens by parsing input.1 * getsym: Look-up symbol in symbol table.1 * putsym: Install symbol in symbol table.L * my_getchar: Return a single character to yylex(), either read from theI * keyboard (in interactive mode) or from the command-line: * "argv" arguments (in command-line mode).* * help: Display the help screen.6 * caltojul: Convert calendar date to julian day.6 * jultocal: Convert julian day to calendar date.- * degtorad: Convert degrees to radians.- * radtodeg: Convert radians to degrees.1 * trunc: Returns its truncated argument. * * inputs :M * Math expression to be calculated, input by the user at the keyboard (inO * interactive mode) or supplied via command-line arguments (in command-line * mode). * * outputs :; * The resultant computed value of the input expression. * * instructions for use :M * This is an "infix" calculator, so any infix expression will be computed * and the result displayed.D * In VAX/VMS, type Ctrl-Z, Ctrl-Y or Ctrl-C to exit the program.9 * In Unix, type Ctrl-D or Ctrl-C to exit the program.E * In PC/MS-DOS, type Ctrl-C or Ctrl-Z+Return to exit the program. * * notes :I * Let me make one thing perfectly clear. I am NOT the author of thisL * program. I merely copied it verbatim out of the "Bison" manual of theO * "Free Software Foundation, Inc.", made some cosmetic changes to customizeJ * it to my particular taste, ran it through "yacc", compiled it with a& * C compiler, and voila! it works. *O * Motivation: I wanted an "infix" calculator for my day-to-day work. ThereJ * is a plethora of Reverse Polish Notation calculators in Unix and theE * public domain, but I haven't seen many infix calculators aroundO * (presumably because they're a bit harder to program than RPN calculators?J * Or maybe I haven't been looking hard enough). I remembered seeing aJ * bison/yacc grammar example to parse an infix calculator in the BisonE * manual of FSF, Inc., and since the manual permits me to copy ittL * (provided FSF is given proper copyright and credit, and this resultingJ * code is placed in the public domain), I used it as a starting point,< * and simply made a FEW modifications to suit my tastes. *J * Since using the Bison manual example mandates me to include the FSF'sM * copyright, their permission notice, the "GNU General Public License" and M * "Conditions for Using Bison" in the resulting derived work, here goes...l7Copyright (C) 1988, 1989 Free Software Foundation, Inc.DPermission is granted to make and distribute verbatim copies of thisCmanual provided the copyright notice and this permission notice arelpreserved on all copies.APermission is granted to copy and distribute modified versions ofoDthis manual under the conditions for verbatim copying, provided also=that the sections entitled ``GNU General Public License'' anda=``Conditions for Using Bison'' are included exactly as in the @original, and provided that the entire resulting derived work isDdistributed under the terms of a permission notice identical to thisone.APermission is granted to copy and distribute translations of thiseEmanual into another language, under the above conditions for modified(@versions, except that the sections entitled ``GNU General PublicDLicense'', ``Conditions for Using Bison'' and this permission notice=may be included in translations approved by the Free Softwaret.Foundation instead of in the original English.Conditions for Using Bison**************************DBison grammars can be used only in programs that are free software. CThis is in contrast to what happens with the GNU C compiler and thevother GNU programming tools.;The reason Bison is special is that the output of the BisoncEutility--the Bison parser file--contains a verbatim copy of a sizabletCpiece of Bison, which is the code for the `yyparse' function. (The @actions from your grammar are inserted into this function at one4point, but the rest of the function is not changed.)AAs a result, the Bison parser file is covered by the same copyingeBconditions that cover Bison itself and the rest of the GNU system:Bany program containing it has to be distributed under the standardGNU copying conditions. :Occasionally people who would like to use Bison to develop)proprietary programs complain about this.hDWe don't particularly sympathize with their complaints. The purposeDof the GNU project is to promote the right to share software and theEpractice of sharing software; it is a means of changing society. TheDpeople who complain are planning to be uncooperative toward the rest;of the world; why should they deserve our help in doing so? >However, it's possible that a change in these conditions mightCencourage computer companies to use and distribute the GNU system. lAIf so, then we might decide to change the terms on `yyparse' as at?matter of the strategy of promoting the right to share. Such ae;change would be irrevocable. Since we stand by the copyingaBpermissions we have announced, we cannot withdraw them once given.EWe mustn't make an irrevocable change hastily. We have to wait untilACthere is a complete GNU system and there has been time to learn how!this issue affects its reception.IGNU GENERAL PUBLIC LICENSE**************************0 Version 1, February 19896 Copyright (C) 1989 Free Software Foundation, Inc.+ 675 Mass Ave, Cambridge, MA 02139, USAn iA Everyone is permitted to copy and distribute verbatim copiesr> of this license document, but changing it is not allowed. Preamblen ========= E The license agreements of most software companies try to keep usersiAat the mercy of those companies. By contrast, our General PublicaALicense is intended to guarantee your freedom to share and changeaDfree software--to make sure the software is free for all its users. DThe General Public License applies to the Free Software Foundation'sDsoftware and to any other program whose authors commit to using it. &You can use it for your programs, too.B When we speak of free software, we are referring to freedom, notDprice. Specifically, the General Public License is designed to makeBsure that you have the freedom to give away or sell copies of freeDsoftware, 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 free4programs; and that you know you can do these things.B To protect your rights, we need to make restrictions that forbidFanyone to deny you these rights or to ask you to surrender the rights.CThese restrictions translate to certain responsibilities for you ife;you distribute copies of the software, or if you modify it.uD For example, if you distribute copies of a such a program, whetherEgratis or for a fee, you must give the recipients all the rights thateDyou have. You must make sure that they, too, receive or can get the2source code. And you must tell them their rights.D We protect your rights with two steps: (1) copyright the software,Band (2) offer you this license which gives you legal permission to,copy, distribute and/or modify the software.F Also, for each author's protection and ours, we want to make certainAthat everyone understands that there is no warranty for this freekEsoftware. If the software is modified by someone else and passed on,l=we want its recipients to know that what they have is not theDoriginal, so that any problems introduced by others will not reflect%on the original authors' reputations. @ The precise terms and conditions for copying, distribution andmodification follow.. TERMS AND CONDITIONS@ 1. This License Agreement applies to any program or other workE which contains a notice placed by the copyright holder saying itu> may be distributed under the terms of this General PublicD License. The ``Program'', below, refers to any such program or? work, and a ``work based on the Program'' means either theNC Program or any work containing the Program or a portion of it, = either verbatim or with modifications. Each licensee is  addressed as ``you''.A 2. You may copy and distribute verbatim copies of the Program'spD source code as you receive it, in any medium, provided that you< conspicuously and appropriately publish on each copy anB appropriate copyright notice and disclaimer of warranty; keepE intact all the notices that refer to this General Public Licensem; and to the absence of any warranty; and give any othergD recipients of the Program a copy of this General Public LicenseC along with the Program. You may charge a fee for the physical0 act of transferring a copy.E 3. You may modify your copy or copies of the Program or any portion @ of it, and copy and distribute such modifications under the> terms of Paragraph 1 above, provided that you also do the following:mE * cause the modified files to carry prominent notices stating8D that you changed the files and the date of any change; andE * cause the whole of any work that you distribute or publish,.C that in whole or in part contains the Program or any part> thereof, either with or without modifications, to beD licensed at no charge to all third parties under the termsD of this General Public License (except that you may chooseD to grant warranty protection to some or all third parties, at your option).9 * If the modified program normally reads commands A interactively when run, you must cause it, when startedeC running for such interactive use in the simplest and mosteE usual way, to print or display an announcement including an D appropriate copyright notice and a notice that there is noD warranty (or else, saying that you provide a warranty) and= that users may redistribute the program under thesetE conditions, and telling the user how to view a copy of this5! General Public License.aE * You may charge a fee for the physical act of transferring aD copy, and you may at your option offer warranty protection in exchange for a fee.B Mere aggregation of another independent work with the ProgramA (or its derivative) on a volume of a storage or distributionB medium does not bring the other work under the scope of these terms.s= 4. You may copy and distribute the Program (or a portion orn; derivative of it, under Paragraph 2) in object code or @ executable form under the terms of Paragraphs 1 and 2 above4 provided that you also do one of the following:6 * accompany it with the complete correspondingA machine-readable source code, which must be distributedt: under the terms of Paragraphs 1 and 2 above; or,E * accompany it with a written offer, valid for at least threetC years, to give any third party free (except for a nominalo9 charge for the cost of distribution) a completeaD machine-readable copy of the corresponding source code, toE be distributed under the terms of Paragraphs 1 and 2 above;: or, D * accompany it with the information you received as to where? the corresponding source code may be obtained. (This1D alternative is allowed only for noncommercial distribution@ and only if you received the program in object code or! executable form alone.)tD Source code for a work means the preferred form of the work forB making modifications to it. For an executable file, complete= source code means all the source code for all modules it*? contains; but, as a special exception, it need not include > source code for modules which are standard libraries that@ accompany the operating system on which the executable fileA runs, or for standard header files or definitions files that % accompany that operating system. E 5. You may not copy, modify, sublicense, distribute or transfer the C Program except as expressly provided under this General Public A License. Any attempt otherwise to copy, modify, sublicense,*9 distribute or transfer the Program is void, and willA automatically terminate your rights to use the Program under A this License. However, parties who have received copies, or E rights to use copies, from you under this General Public License*D will not have their licenses terminated so long as such parties remain in full compliance.pC 6. By copying, distributing or modifying the Program (or any work ? based on the Program) you indicate your acceptance of this 8 license to do so, and all its terms and conditions.E 7. Each time you redistribute the Program (or any work based on the B Program), the recipient automatically receives a license fromD the original licensor to copy, distribute or modify the ProgramC subject to these terms and conditions. You may not impose any(C further restrictions on the recipients' exercise of the rightsu granted herein.@ 8. The Free Software Foundation may publish revised and/or newD versions of the General Public License from time to time. SuchC new versions will be similar in spirit to the present version,cB but may differ in detail to address new problems or concerns.C Each version is given a distinguishing version number. If the D Program specifies a version number of the license which applies< to it and ``any later version'', you have the option ofD following the terms and conditions either of that version or ofE any later version published by the Free Software Foundation. IfB the Program does not specify a version number of the license,C you may choose any version ever published by the Free Software  Foundation.D 9. If you wish to incorporate parts of the Program into other freeC programs whose distribution conditions are different, write to = the author to ask for permission. For software which isaC copyrighted by the Free Software Foundation, write to the Free E Software Foundation; we sometimes make exceptions for this. OurdD decision will be guided by the two goals of preserving the freeD status of all derivatives of our free software and of promoting1 the sharing and reuse of software generally. . NO WARRANTY@ 10. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NOD 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 OFa? MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THExD ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM ISB WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE; COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.eB 11. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO INB WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAYB MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE? LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, B INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE ORD INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSSE OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BYuE YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITHyE ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEENo0 ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.1 END OF TERMS AND CONDITIONSo7Appendix: How to Apply These Terms to Your New Programsy7======================================================= E If you develop a new program, and you want it to be of the greatestnDpossible use to humanity, the best way to achieve this is to make itDfree software which everyone can redistribute and change under theseterms.F To do so, attach the following notices to the program. It is safestCto attach them to the start of each source file to most effectivelyrDconvey the exclusion of warranty; and each file should have at leastGthe ``copyright'' line and a pointer to where the full notice is found. J ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.' Copyright (C) 19YY NAME OF AUTHORl I This program is free software; you can redistribute it and/or modify I it under the terms of the GNU General Public License as published byH the Free Software Foundation; either version 1, or (at your option) any later version.  uD This program is distributed in the hope that it will be useful,C but WITHOUT ANY WARRANTY; without even the implied warranty of B MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1 GNU General Public License for more details.  F 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., 675 Mass Ave, Cambridge, MA 02139, USA.C Also add information on how to contact you by electronic and papertmail.iAIf the program is interactive, make it output a short notice like +this when it starts in an interactive mode:f> Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHORN Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.B This is free software, and you are welcome to redistribute it9 under certain conditions; type `show c' for details.s@ 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' andA`show c'; they could even be mouse-clicks or menu items--whateverysuits your program. BYou should also get your employer (if you work as a programmer) or?your school, if any, to sign a ``copyright disclaimer'' for theo7program, if necessary. Here a sample; alter the names:xC Yoyodyne, Inc., hereby disclaims all copyright interest in thenH program `Gnomovision' (a program to direct compilers to make passes, at assemblers) written by James Hacker. ' SIGNATURE OF TY COON, 1 April 1989F Ty Coon, President of Vice That's all there is to it! *9 * There! I've done it, and now my conscience is clear!a *M * As the good license above says, folks, this code is in the public domain,oM * and is to be distributed under the terms of a permission notice identicalr) * to the GNU license. So, here goes...s * nL * This program is free software; you can redistribute it and/or modifyL * it under the terms of the GNU General Public License as published byK * the Free Software Foundation; either version 1, or (at your option)l * any later version. * G * This program is distributed in the hope that it will be useful,aF * but WITHOUT ANY WARRANTY; without even the implied warranty ofE * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See then4 * GNU General Public License for more details. * I * You should have received a copy of the GNU General Public License C * along with this program; if not, write to the Free SoftwareA * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *1 * Now that that's done, let us on, let us on...m * * features :mI * 1) Addition (+), Subtraction (-), Multiplication (*), Division (/) * 2) Modulus (%), Power (^)O * 3) Bitwise logical operators: bitwise AND (&), bitwise inclusive OR (|),y$ * unary one's complement (~)K * 4) 20 Math/Trigonometric functions: sin, cos, tan, asin, acos, atan,t@ * sinh, cosh, tanh, exp (exponential), ln (natural log),G * log (base 10 log), sqrt (square root), ceil (ceiling), floor,t7 * int/trunc (truncation), abs (absolute value), C * degtorad (degrees->radians), radtodeg (radians->degrees).aO * Two Date functions to convert between calendar dates and julian days:lF * caltojul (calendar->julian) and jultocal (julian->calendar).< * One '?'-for-help command to display a help screen.M * 5) Temporary variables (as many as you want, with names as long as youn3 * want) to store intermediate computations. P * 6) This is a "portable" calculator in the sense that it's not specific toN * any operating system. The yacc output should be compilable by any CP * compiler; this program has been tested on Unix, VAX/VMS and PC/MS-DOS,1 * and has required no changes to compile. O * 7) This program uses the simplest of input and output formats, and is indM * no way hardware dependent. So, as long as it compiles and executes,N * without any problems, there are no other requirements for it to work * as advertised.G * 8) All numbers are of the C floating-point type "double", which,F * according to the VAX C manual, has a range of 0.29*10^-38 toA * 1.7*10^38, and has values precise to 16 decimal digits.rF * 9) Allows any number of expressions on a line, separated by ';'? * 10) icalc can now be run either interactively (when it ispB * invoked without any arguments, in which case the user isA * prompted for input) or in a command-line mode (when all=< * expressions to be computed are passed to icalc viaE * command-line "argv" arguments, in which case icalc computesrC * and prints the result of each expression -- exactly as ifd? * it had been entered interactively -- and then exits).l> * In the latter case, the user is supposed to delimit/) * separate the expressions by ';'e * * limitations : H * 1) This is a simple calculator that works only in character mode.J * No jazzy graphics, no explanatory error messages, nothin' fancy.N * 2) This calculator is only double precision and NOT infinite precision. * * references :t@ * The "Bison" manual of the "Free Software Foundation, Inc." *J ************************************************************************* */yC#include /* For math functions, cos(), sin(), etc. */oI/* #include "calc.h" */ /* Contains definition of `symrec' */ J/* ^^^^^^^^^^^^^^^^^ instead of having another one-time-only include file,O * the file itself has been physically included here */O/*-- calc.h -----------------------------------------------------------------*/oC/* Data type for links in the chain of symbols. */Y struct symrecr{h7 char *name; /* name of symbol */o7 int type; /* type of symbol: either VAR or FNCT */s union {t7 double var; /* value of a VAR */l7 double (*fnctptr)(); /* value of a FNCT */u } value;7 struct symrec *next; /* link field */n};typedef struct symrec symrec;h7/* The symbol table: a chain of `struct symrec'. */fextern symrec *sym_table;tsymrec *putsym ();symrec *getsym ();O/*-- end of calc.h ----------------------------------------------------------*/o# line 565 "icalc.y"typedef union {>double val; /* For returning numbers. */>symrec *tptr; /* For returning symbol-table pointers */ } YYSTYPE;# define NUM 257# define VAR 258# define FNCT 259# define NEG 260#define yyclearin yychar = -1m#define yyerrok yyerrflag = 0aextern int yychar;extern short yyerrflag;a#ifndef YYMAXDEPTH#define YYMAXDEPTH 150#endifYYSTYPE yylval, yyval;# define YYERRCODE 256# line 628 "icalc.y"O/*== additional C code ======================================================*/#include int interactive; char *sargs;4double caltojul(); /* calendar date -> julian day */4double jultocal(); /* julian day -> calendar date */+double degtorad(); /* degrees -> radians */o+double radtodeg(); /* radians -> degrees */edouble trunc(); /* truncate */tmain(argc, argv) int argc; char **argv;i{o) char *version = "2.2 of 17-MAR-1992";n-/* char *version = "2.1 of 16-MAR-1992"; */t-/* char *version = "2.0 of 14-DEC-1991"; */P-/* char *version = "1.1 of 16-AUG-1990"; */w-/* char *version = "1.0 of 8-JUL-1990"; */f init_table (); if (argc == 1) { interactive = 1; printf("IC> ");o } else { interactive = 0; /*M * contruct a single string "sargs" comprising all argv strings in order,PM * with a single space separating each argv element (this is not strictlyuN * necessary since the user is supposed to separate all expressions passedK * through argv with ';' already, but it may be useful in the future tot * know this).K * signal the end of the string with '\n' followed by NULL (the '\n' ishE * required for the way ICALC works, and the NULL will act as the 7 * equivalent of an EOF in an interactive session).  */o1 sargs = (char *) malloc(strlen(argv[1]) + 2);  strcpy(sargs, argv[1]);o argc--;r argv++;e while (--argc) {M sargs = (char *) realloc(sargs, strlen(sargs)+1 + strlen(*++argv)+2);aJ strcat(sargs, " "); /* argv separator -- not strictly necessary */ strcat(sargs, *argv);a }l+ sargs[strlen(sargs) + 1] = (char) NULL;h$ sargs[strlen(sargs)] = '\n'; } yyparse ();o}uO/*---------------------------------------------------------------------------*/l#define BEL 0x7i-yyerror (s) /* Called by yyparse on error */i char *s; {t( printf ("%c%s\n", BEL, s); /* Beep! */}yO/*---------------------------------------------------------------------------*/g struct initt{  char *fname; double (*fnct)();s};struct init arith_fncts[]  = {  "sin", sin, "sinh", sinh, "asin", asin, "cos", cos, "cosh", cosh, "acos", acos, "tan", tan, "tanh", tanh, "atan", atan, "exp", exp, "ln", log,a "log", log10, "sqrt", sqrt, "ceil", ceil, "floor", floor, "int", trunc, "trunc", trunc, "abs", fabs,  "caltojul", caltojul,s "jultocal", jultocal,i "degtorad", degtorad,r "radtodeg", radtodeg,i 0, 0g };8/* The symbol table: a chain of `struct symrec'. */ symrec *sym_table = (symrec *)0;O/*---------------------------------------------------------------------------*/p8init_table () /* puts arithmetic functions in table. */{c int i; symrec *ptr;- for (i = 0; arith_fncts[i].fname != 0; i++)b {,0 ptr = putsym (arith_fncts[i].fname, FNCT);/ ptr->value.fnctptr = arith_fncts[i].fnct;e }i}pO/*---------------------------------------------------------------------------*/csymrec *putsym (sym_name,sym_type) char *sym_name; int sym_type;{  symrec *ptr;+ ptr = (symrec *) malloc (sizeof(symrec));e3 ptr->name = (char *) malloc (strlen(sym_name)+1);  strcpy (ptr->name,sym_name); ptr->type = sym_type;s9 ptr->value.var = 0; /* set value to 0 even if fctn. */e) ptr->next = (struct symrec *)sym_table;i sym_table = ptr; return ptr;o}eO/*---------------------------------------------------------------------------*/usymrec *getsym (sym_name)r char *sym_name;{f symrec *ptr;, for (ptr = sym_table; ptr != (symrec *) 0;! ptr = (symrec *)ptr->next)l) if (strcmp (ptr->name,sym_name) == 0)c return ptr;s return 0;i} O/*---------------------------------------------------------------------------*/t#include /*O * This lexical analyzer has been hand-coded, but in return for its simplicity,rH * it has the restriction that only single-character tokens are allowed.L * For multiple-character tokens, you might consider replacing the following* * 'yylex' with REAL lex-generated source. */Pyylex() {c int c;9 /* Ignore whitespace, get first nonwhite character. */b2 while ((c = my_getchar ()) == ' ' || c == '\t'); if (c == EOF)i return 0;s9 /* Char starts a number => parse the number. */i if (c == '.' || isdigit (c)) {r if (interactive) { ungetc (c, stdin);# scanf ("%lf", &yylval.val);l } else { sargs--;+ sscanf (sargs, "%lf", &yylval.val); /*N * move the sargs pointer to the spot where sscanf() left off scanning */c move_sargs();t }  return NUM;a }i9 /* Char starts an identifier => read the name. */h if (isalpha (c)) {d symrec *s; static char *symbuf = 0; static int length = 0; int i;. /* Initially make the buffer long enough, for a 40-character symbol name. */ if (length == 0): length = 40, symbuf = (char *)malloc (length + 1); i = 0; do {3 /* If buffer is full, make it bigger. */  if (i == length) {b length *= 2;< symbuf = (char *)realloc (symbuf, length + 1); }c3 /* Add this character to the buffer. */m7 symbuf[i++] = isupper(c) ? tolower(c) : c; /*h * "tolower" makes  * variable names * case-INsensitive * by converting them * ALL to lower-case. */3 /* Get another character. */r c = my_getchar (); }r& while (c != EOF && isalnum (c)); if (interactive) ungetc (c, stdin); else sargs--; symbuf[i] = '\0';s s = getsym (symbuf); if (s == 0)u! s = putsym (symbuf, VAR);o yylval.tptr = s; return s->type;  }r3 /* Any other character is a token by itself. */t return c;a}oO/*---------------------------------------------------------------------------*/w my_getchar(){t int c;F if (interactive)o return getchar();s else {e c = *sargs;. if (c) { sargs++; return c;s } else return EOF;o }}O/*---------------------------------------------------------------------------*/ move_sargs(){ /*BB * At the point when this routine is called, the sargs pointer isE * sitting at the beginning of a floating-point number (we also know F * that the character at the head of this number is either a '.' or a * digit.E * This routine should move the sargs pointer to the spot/point/char,G * on the string where the preceding sscanf() call should have stoppedM * scanning.S */R /*I! * Floating-point number format:U: * [ + | - ] nnn [ . [ ddd ] ] [ { E | e } [ + | - ] nn ] */ /*RE * I'm starting with the assumption that *sargs is either a digit orE * the character '.'N */ while (isdigit(*sargs)) sargs++; switch (*sargs) { case '.':  switch (*++sargs) { case '0':I case '1':O case '2': case '3':R case '4': case '5':R case '6': case '7':I case '8': case '9':Y while (isdigit(*sargs)) sargs++; switch (*sargs) { case 'E':S case 'e':H break;I default: return; } case 'E':T case 'e': break;B default: return; } case 'E':u case 'e': break;E default: return; }A /* If control has dropped to this point, *sargs is 'E' or 'e' */O switch (*++sargs) { case '+':O case '-':L switch (*++sargs) { case '0': case '1':R case '2':N case '3': case '4':e case '5':r case '6': case '7':= case '8':= case '9':= break; default: return; } case '0':o case '1':e case '2':b case '3':a case '4':t case '5':v case '6':m case '7':s case '8': case '9':r while (isdigit(*sargs)) sargs++; return; default: return; }}sO/*---------------------------------------------------------------------------*/mhelp(){lD /* display a help screen of all supported commands and functions */] printf("Arithmetic Operators: Trig Functions (take radian arguments):\n");GN printf("+ Addition (plus) sin sine\n");Y printf("- Subtraction (minus) sinh hyperbolic sine\n");/R printf("* Multiplication (times) asin arc sine\n");P printf("/ Division (divided by) cos cosine\n");\ printf("%% Modulus (remainder) cosh hyperbolic cosine\n");T printf("^ Power (raised to) acos arc cosine\n");Q printf("Bitwise Logical Operators: tan tangent\n");i\ printf("& bitwise AND tanh hyperbolic tangent\n");U printf("| bitwise inclusive OR atan arc tangent\n");dE printf("~ unary one's complement Math Functions:\n");mX printf("Date Functions: exp exponentiation\n");U printf("caltojul calendar to julian date ln natural log\n");U printf(" Usage: caltojul(yyyy, mm, dd) log base 10 log\n");sU printf(" Returns: #days elapsed since October 15, 1582 sqrt square root\n");nQ printf("jultocal julian to calendar date ceil ceiling\n");fO printf(" Usage: jultocal(julian_date) floor floor\n");T printf(" Returns: date in yyyymmdd format int,trunc truncation\n");X printf(" Eg: caltojul(1989,12,31) <=> jultocal(148732) abs absolute value\n");\ printf("Help Functions: degtorad degrees -> radians\n");\ printf("? Help (print this screen) radtodeg radians -> degrees\n");}iO/*---------------------------------------------------------------------------*/a/*6 * function to convert calender dates to julian dates.4 * (originally adapted from ACM, Oct '68, page 657).: * This function assumes dayzero=yrmoda/julian/spss/sir =>* * assumes idayzer=2299160 (Oct 15, 1582). */ddouble caltojul(yyyy, mm, dd)i double yyyy, mm, dd;!{'6 long idayzer, i, j, k, ci2j; /* DON'T use "unsigned"!( * ci2j calculation will blow up */ idayzer = 2299160;o i = yyyy; j = mm; k = dd;@ ci2j = k-32075+1461*(i+4800+(j-14)/12)/4+367*(j-2-(j-14)/12*12)- /12-3*((i+4900+(j-14)/12)/100)/4 - idayzer;  return( (double) ci2j );r}yO/*---------------------------------------------------------------------------*/ #ifndef absa>#define abs(x) ((x) < 0 ? (-(x)) : (x)) /* absolute val */#endifO/*---------------------------------------------------------------------------*/ double jultocal(jd) double jd;b{s /*a5 * function to convert julian days to calendar datesp * (converse of caltojul)' * idayzer -- julian day-one offsetU: * i,j,k,l,n -- integer ease transcription of algorithm 4 * dd,mm,yyyy -- day,month,year digits respectively. * jd -- incoming integer julian date@ * jdz -- local integer julian date has dayzero addedon; * converts julian date 'jd' with specifiable first day toA1 * gregorian date with output format 'yyyymmdd'. E * uses acm algorithm by hf fliegel, and tc van flandern acm vol 11,a * #10,oct68.? * dayone is a string indicating first julian day of calendar. B * algorithm uses prehistoric day-one, so 2299161 is oct 15, 1582" * used by spss/sir for base date */0 long idayzer, jdz, i, j, k, l, n, yyyy, mm, dd; idayzer = 2299160; jdz = abs((long) jd) + idayzer;- /* i is julian year, j is month, k is day */o l = jdz + 68569;  n = 4*l/146097; l = l - (146097*n + 3)/4; i = 4000*(l+1)/1461001; l = l - 1461*i/4 + 31; j = 80*l/2447;d k = l - 2447*j/80;r l = j/11; j = j + 2 - 12*l; i = 100*(n - 49) + i + l; yyyy = i; mm = j; dd = k;3 return( (double) (yyyy * 10000 + mm * 100 + dd) ); }tO/*---------------------------------------------------------------------------*/e!#define PI 3.14159265358979323846 O/*---------------------------------------------------------------------------*/ double degtorad(x) double x;{p+ return( x * (PI / 180.0) ); /* deg->rad */t}eO/*---------------------------------------------------------------------------*/adouble radtodeg(x) double x;{m+ return( x * (180.0 / PI) ); /* rad->deg */O}O/*---------------------------------------------------------------------------*/ double trunc(x)n double x;{s$ return( (long) x ); /* truncate */}eO/*== end of additional C code ===============================================*/ short yyexca[] ={r-1, 1, 0, -1,t -2, 0, }; # define YYNPROD 26*# define YYLAST 250rshort yyact[]={n2 3, 13, 25, 22, 23, 26, 11, 46, 20, 18,2 47, 19, 27, 21, 22, 23, 14, 17, 43, 20,2 18, 44, 19, 16, 21, 4, 2, 1, 22, 23,2 13, 0, 49, 20, 18, 11, 19, 0, 21, 22,2 23, 0, 0, 42, 20, 18, 0, 19, 0, 21,2 0, 22, 23, 6, 0, 0, 20, 18, 0, 19,2 25, 21, 22, 23, 22, 15, 0, 20, 18, 20,2 19, 25, 21, 22, 21, 0, 0, 0, 20, 18,2 0, 19, 0, 21, 0, 25, 0, 12, 0, 0,2 24, 0, 0, 0, 0, 0, 25, 0, 0, 0,2 0, 24, 0, 0, 0, 0, 0, 0, 25, 0,2 0, 0, 0, 0, 0, 24, 12, 0, 0, 25,2 7, 25, 0, 0, 0, 0, 24, 0, 0, 0,2 25, 0, 28, 29, 30, 0, 31, 0, 24, 32,2 33, 34, 35, 36, 37, 38, 39, 40, 41, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 45, 0, 0, 48, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 8, 9,2 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,4 0, 0, 0, 0, 0, 0, 5, 8, 9, 10 };short yypact[]={6-1000, -10,-1000,-1000, 6, 13, 7, 14,-1000, -56,5 -28, -39, -39, -39,-1000, -39,-1000,-1000, -39, -39,^2 -39, -39, -39, -39, -39, -39, -39, -39, -92, -92,2 2, 14, 27, 27, -92, -92, -92, 36, 25, -92,8 14, -23,-1000,-1000, -39, -34,-1000, -39, -9,-1000 };short yypgo[]={- 0, 120, 27, 26, 25 };-short yyr1[]={2 0, 2, 2, 3, 3, 3, 3, 4, 4, 1,2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };short yyr2[]={2 0, 0, 2, 1, 2, 2, 2, 1, 3, 1,2 1, 3, 4, 6, 8, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3 };short yychk[]={e3-1000, -2, -3, 10, -4, 256, 63, -1, 257, 258,x2 259, 45, 126, 40, 10, 59, 10, 10, 43, 45,2 42, 47, 37, 38, 124, 94, 61, 40, -1, -1,2 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,4 -1, -1, 41, 41, 44, -1, 41, 44, -1, 41 };short yydef[]={-2 1, -2, 2, 3, 0, 0, 0, 7, 9, 10,2 0, 0, 0, 0, 4, 0, 5, 6, 0, 0,2 0, 0, 0, 0, 0, 0, 0, 0, 22, 23,2 0, 8, 15, 16, 17, 18, 19, 20, 21, 24,4 11, 0, 25, 12, 0, 0, 13, 0, 0, 14 }; #ifndef lintDstatic char yaccpar_sccsid[] = "@(#)yaccpar 4.1 (Berkeley) 2/11/83";#endif not lint #f# define YYFLAG -1000c# define YYERROR goto yyerrlab# define YYACCEPT return(0)Y# define YYABORT return(1)/* parser for yacc output */#ifdef YYDEBUG&int yydebug = 0; /* 1 for debugging */#endif:YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */1int yychar = -1; /* current input token number */(int yynerrs = 0; /* number of errors *//short yyerrflag = 0; /* error recovery flag */a yyparse() { short yys[YYMAXDEPTH];r short yyj, yym; register YYSTYPE *yypvt;i$ register short yystate, *yyps, yyn; register YYSTYPE *yypv; register short *yyxi; yystate = 0;o yychar = -1;s yynerrs = 0;7 yyerrflag = 0;  yyps= &yys[-1]; yypv= &yyv[-1];7 yystack: /* put a state and value onto the stack */ #ifdef YYDEBUGB if( yydebug ) printf( "state %d, char 0%o\n", yystate, yychar );#endifQ if( ++yyps> &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); }  *yyps = yystate; ++yypv; *yypv = yyval; yynewstate: yyn = yypact[yystate];l6 if( yyn<= YYFLAG ) goto yydefault; /* simple state */2 if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0;9 if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault;s= if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */  yychar = -1; yyval = yylval;o yystate = yyn;" if( yyerrflag > 0 ) --yyerrflag; goto yystack;L } yydefault:* /* default state action */o# if( (yyn=yydef[yystate]) == -2 ) { 5 if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0; $ /* look through exception table */S for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */l while( *(yyxi+=2) >= 0 ){c if( *yyxi == yychar ) break;s }5 if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */g }a if( yyn == 0 ){ /* error */+ /* error ... attempt to resume parsing */  switch( yyerrflag ){! case 0: /* brand new error */r yyerror( "syntax error" );s yyerrlab: ++yynerrs;- case 1:-: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; ; /* find a state where "error" is a legal shift action */r while ( yyps >= yys ) {& yyn = yypact[*yyps] + YYERRCODE;F if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){A yystate = yyact[yyn]; /* simulate a shift of "error" */n goto yystack; } yyn = yypact[*yyps];@ /* the current yyps has no shift onn "error", pop stack */#ifdef YYDEBUG] if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );a#endif --yyps; --yypv;s } E /* there is no state on the stack with an error shift ... abort */u yyabort: return(1);a1 case 3: /* no shift yet; clobber input char */u#ifdef YYDEBUGG if( yydebug ) printf( "error recovery discards char %d\n", yychar );#endif@ if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ yychar = -1;7 goto yynewstate; /* try again in the same state */- } }-" /* reduction by production yyn */#ifdef YYDEBUG* if( yydebug ) printf("reduce %d\n",yyn);#endif yyps -= yyr2[yyn]; yypvt = yypv; yypv -= yyr2[yyn]; yyval = yypv[1]; yym=yyn;. /* consult goto table to find next state */ yyn = yyr1[yyn]; yyj = yypgo[yyn] + *yyps + 1;-Y if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];  switch(yym){ case 3:t# line 592 "icalc.y"3{ if (interactive) printf("IC> "); } break;tcase 4: # line 593 "icalc.y"3{ if (interactive) printf("IC> "); } break;tcase 5: # line 594 "icalc.y" { yyerrok;H if (interactive) printf("IC> "); } break;case 6: # line 596 "icalc.y"%{ help(); /* display a help screen */-H if (interactive) printf("IC> "); } break;case 7:_# line 601 "icalc.y"6{ printf(" %.10g\n", yypvt[-0].val); } break;case 8:c# line 602 "icalc.y"6{ printf(" %.10g\n", yypvt[-0].val); } break;case 9:# line 605 "icalc.y"={ yyval.val = yypvt[-0].val; } break;-case 10:# line 606 "icalc.y">{ yyval.val = yypvt[-0].tptr->value.var; } break;case 11:# line 607 "icalc.y"G{ yyval.val = yypvt[-0].val; yypvt[-2].tptr->value.var = yypvt[-0].val;k= printf(" %s = %.10g\n",o_ yypvt[-2].tptr->name, yypvt[-0].val); } break;case 12:# line 610 "icalc.y"I{ yyval.val = (*(yypvt[-3].tptr->value.fnctptr))(yypvt[-1].val); } break; case 13:# line 611 "icalc.y"X{ yyval.val = (*(yypvt[-5].tptr->value.fnctptr))(yypvt[-3].val, yypvt[-1].val); } break;case 14:# line 612 "icalc.y"g{ yyval.val = (*(yypvt[-7].tptr->value.fnctptr))(yypvt[-5].val, yypvt[-3].val, yypvt[-1].val); } break;{case 15:# line 613 "icalc.y"H{ yyval.val = yypvt[-2].val + yypvt[-0].val; } break;case 16:# line 614 "icalc.y"H{ yyval.val = yypvt[-2].val - yypvt[-0].val; } break;case 17:# line 615 "icalc.y"H{ yyval.val = yypvt[-2].val * yypvt[-0].val; } break;case 18:# line 616 "icalc.y"H{ yyval.val = yypvt[-2].val / yypvt[-0].val; } break;case 19:# line 617 "icalc.y"H{ yyval.val = fmod(yypvt[-2].val, yypvt[-0].val); } break;case 20:# line 618 "icalc.y"H{ yyval.val = ((int) yypvt[-2].val) & ((int) yypvt[-0].val); } break;case 21:# line 619 "icalc.y"H{ yyval.val = ((int) yypvt[-2].val) | ((int) yypvt[-0].val); } break;case 22:# line 620 "icalc.y"={ yyval.val = -yypvt[-0].val; } break;ccase 23:# line 621 "icalc.y"={ yyval.val = ~((int) yypvt[-0].val); } break;lcase 24:# line 622 "icalc.y"H{ yyval.val = pow (yypvt[-2].val, yypvt[-0].val); } break;case 25:# line 623 "icalc.y"={ yyval.val = yypvt[-1].val; } break;a } 0 goto yystack; /* stack new state and value */ }N/*== End of ICALC.C == End of ICALC.C == End of ICALC.C == End of ICALC.C ==*/