C SCIENTIFIC FUNCTION CALLER C This version is a dummy placeholder. C The SCIFCT subroutine exists to allow AnalytiCalc to call just C about *ANY* Fortran callable routine. C The operation is to use a formula in AnalytiCalc which includes c a call of form: c *U STxxxxxx range;range;range;range;range;...;range>outrange;outrange;outrange c so that the "xxxxxx" part is the function name to be called. c input ranges are the parts of the sheet for input to the function; these c are internally copied to a large array (defined here) which is a normal c Fortran array. They are converted to integer*4 as needed if the function c being called needs this. Once all conversion is done, the subroutine is c called using an argument list built up by this call list. At the end, c the output ranges are filled in from the internal Fortran array. c Because Fortran callable subroutines (e.g. those in the SSP) may pass c their return arguments in ANY of their arguments, seeing a ; will increment c the output range counter. c c To add more: c * Select desired sizes for work area (must be big enough to hold ALL c arguments used), max number of arguments per function, etc. c * Add new function name and characteristics to tables. Note that the c name, integer/float stuff for all args, which arg is first OUTPUT arg, c and map of output args, all are needed. Don't make first output arg c bigger than the max. number of args. c * Add another call and element in the computed GOTO for each function c desired. c * Build and enjoy. c c Internally we need tables of c * Function names (up to 6 characters long per classical Fortran rules) c * Number of arguments needed per function c * Integer/real flags for arguments' data types c * First output argument number (user convenience and less error c prone than having to have a bunch of ;;;;'s to force the c outputrange to come from the right area c * Length of the Fortran array used for each input argument c Note: Provision is made for "scratch array" arguments, but is a bit c crude. However, if extra space is needed, user can specify a larger c input area and the larger chunk of scratch space will be present. c Unused argument areas will generally be zeroed on each call. c It is perfectly reasonable to have input-only functions (e.g. plots) c or several subroutines called in sequence for a function. c c *** Fill in *** c BigSpc is the number of floating point words in the scratch array. c All arguments to the functions MUST FIT in this area. No error is c returned here if too much space is needed; the array is just not c overrun. Make sure this is enough, and if you like, provide checks c on the space used in your call. These example calls do not do so, c but you can modify that if you want. Since this array just sits c around until you use any *U STxxxxxx functions, don't make it a lot c bigger than needed either. Parameter (BigSpc=1024) c c MaxArgs is the maximum number of arguments used by any function. Since c many arrays have this as one dimension, be conservative. Must be at c least as large as the argument list of the longest function argument c list called. Parameter (MaxArgs=10) c c NFCT is the number of function calls here. Parameter (NFCT=5) c NFCT is number of functions included in the list. Update the parameter c and the tables together (please!) c c c NARGIN is the number of input arguments. If this many input arguments c are not seen, an error is returned and the function is NOT called. c Usually it's just the number of arguments the function has. Integer*4 NARGin(NFct) c nargin is number input args needed. c outarg is a set of FLAGS that tell whether an argument is an output c argument or not. 1 means it IS an output argument, 0 means it's NOT c an output argument. Be sure to set them correctly. Integer*4 OutArg(MaxArgs,NFct) c c Some subroutine packages expect to see arrays stored (row, column) c and others expect (column, row). If RevStr is zero for an argument c a row first copy will be made; if it is 1, a column first copy will c be made to the scratch array, or from the scratch array back to c the spreadsheet. This permits both sorts of routines to be accomodated. Integer*4 RevStr(MaxArgs,NFct) c RevStr will be nonzero to reverse storage of arrays c from normal row-first to column-first order. c c c OutBgn just tells which argument is the first output argument c for a function. It should be less than maxargs, but is otherwise c arbitrary. It should be the number of the first output argument c (counting from 1 as the first function argument) of the function. Integer*4 OutBgn(NFct) c OutArg is 0 for no output, 1 for output area c c c This routine knows how to handle subroutine arguments which are either c real*8 (floating point) or Integer*4 (integer). the IsReal array has c flags to specify which is which. These flags tell whether the number c obtained from the spreadsheet should be presented to the subroutine c converted to integer, or converted to float (or left as integer/float c if they were correct already). Spreadsheet cells can be either integer c or float too. They are converted to float internally, then converted to c the correct representation for the subroutine. Since the float c representation is double precision, no loss of precision occurs. Integer*4 IsReal(MaxArgs,NFCT) c C Since there are some subs that need dummy argument scratch c areas, encode IsReal as follows: c 0 = Real c -1 = Integer c +nn = Use argument nn's VALUE (after grabbing it) for c size of area to allocate. Always allocate floats c since they're longer. c c Note: Due to the way the program allocates scratch array, the c arguments with size info for dummy arrays must be present c ahead of the scratch space arguments. c Integer*2 OutTyp(MaxArgs) c c c The function names used in the spreadsheet must be entered here. c The FNameB array is these function names. Logical*1 FNameB(6,NFCT) c allows access of function names by byte, but data stmts to set up c as full names... c This example has 5 functions: c the first two are c *U STDLLSQ and c *U STCHISQ c from the Scientific Subroutine Package library... Data FnameB/ 1 'D','L','L','S','Q',0, 2 'C','H','I','S','Q',0, 3 'V','E','C','N','O','R', 4 'A','S','Y','M', 0 ,0, 4 'A','S','U','M', 0 ,0 / DATA IsReal/ 1 0,0,-1,-1,-1,0,5,0,-1,0, 2 0,-1,-1,0,-1,-1,2,3,0,0, 3 0,-1,0,0,0,0,0,0,0,0, 4 0,-1,-1,0,0,0,0,0,0,0, 5 0,-1,-1,0,-1,0,0,0,0,0 / DATA OutBgn/ 1 6,4,3,4,4 / DATA OutArg/ 1 0,0,0,0,0,1,0,0,1,1, 2 0,0,0,1,1,1,0,0,0,0, 3 0,0,1,0,0,0,0,0,0,0, 4 0,0,0,1,0,0,0,0,0,0, 5 0,0,0,1,1,0,0,0,0,0 / c Note OutArg is just which output arguments are really c output data. 1 means they are, 0 means they're not. c C NARGIN is min number input arguments that must be present. Data NARGin/10,8,3,4,5/ Data RevStr/ 1 0,0,0,0,0,0,0,0,0,0, 2 0,0,0,0,0,0,0,0,0,0, 3 0,0,0,0,0,0,0,0,0,0, 4 0,0,0,0,0,0,0,0,0,0, 5 0,0,0,0,0,0,0,0,0,0 / "Giant" AnalytiCalc This version of AnalytiCalc differs from the older one in two respects: 1. It allows far more cells. Internal limits of 16 bits on cell numbers are removed, so cell numbers can now be 32 bits long. Less word and more longword math seem to speed it up also. 2. A new addressing form was added. In addition to being able to specify cells with a form P#%cr where c and r are one letter accumulator names holding OFFSETS from the current cell in columns and rows, you can now also use the form (in this version only) P#_cr where c and r are the ABSOLUTE column and row in the cell. Note that row 0 of the spreadsheet consists of the accumulators, so cell A1 is at column 1, row 1, where accumulator A is in column 1 row 0. The *U HERE function returns these addresses, as do other functions returning cell locations. C and R must be single letters, denoting accumulators containing column and row; any letters are legal. Hopefully this feature will allow elimination of some address arithmetic. (It was a VERY small change.) Another new addressing form added allows use of cell addresses of the form P#$V1:V2: where V1 and V2 are any other cell addresses (except P#$v1:v2: forms). This works EXACTLY like the P#_cr form except that any cell can be used to hold column and row addresses, not just one of the accumulators. Glenn Everhart 4/3/1989