Various Datatypes.
[AROS-Contrib.git] / fish / eval / funcs.c
blob8e882667370b8c36acb7f5338e7e066959fc311f
1 /*
2 **
3 ** FUNCS.C A module to be included with EVAL.C that handles
4 ** the manipulation of functions.
5 **
6 ** Originally written 5/89 in ANSI C
7 **
8 ** To add/change the functions in Eval:
9 ** --------------------------------------------------------------
10 ** 1. If the name of your function is longer than MAXFLEN, or the
11 ** argument list string is longer than MAXALEN, then increase the
12 ** size of these defines (MAXFLEN in eval.h, MAXALEN in funcs.c).
13 ** 1. Update the value of NUMFUNCS in eval.h (total number of functions).
14 ** 2. Add a #define for any new functions to the list of #defines
15 ** below. You do not need to keep the list in alphabetic order.
16 ** 3. Add the function ID (#define tag), name, argument list, and a
17 ** brief descripton to the flist[] array below. Please keep the list
18 ** in alphabetic order by function name.
19 ** 4. Add the actual function code to the func_eval function below.
20 ** Follow the examples of other functions.
21 ** 5. If necessary, add the C-code for new math functions to emath.c,
22 ** and add prototypes for new C math functions to eval.h
23 ** NOTICE: Read the disclaimer about adding code to emath.c in
24 ** the comments of emath.c.
25 ** 6. Recompile ALL modules.
28 ** Eval is a floating point expression evaluator.
29 ** This is version 1.12
30 ** Copyright (C) 1993 Will Menninger
32 ** This program is free software; you can redistribute it and/or modify it
33 ** under the terms of the GNU General Public License as published by the
34 ** Free Software Foundation; either version 2 of the License, or any
35 ** later version.
37 ** This program is distributed in the hope that it will be useful, but
38 ** WITHOUT ANY WARRANTY; without even the implied warranty of
39 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40 ** General Public License for more details.
42 ** You should have received a copy of the GNU General Public License along
43 ** with this program; if not, write to the Free Software Foundation, Inc.,
44 ** 675 Mass Ave, Cambridge, MA 02139, USA.
46 ** The author until 9/93 can be contacted at:
47 ** e-mail: willus@ilm.pfc.mit.edu
48 ** U.S. mail: Will Menninger, 45 River St., #2, Boston, MA 02108-1124
52 #include "eval.h"
54 #define MAXALEN 3
55 #define MAXDLEN 80
57 typedef struct {
58 int id;
59 char name[MAXFLEN+1];
60 char argspec[MAXALEN+1];
61 char desc[MAXDLEN+1];
62 } FUNC, *FUNCPTR;
64 #define ABSVAL 1
65 #define ACOS 2
66 #define ACOSH 3
67 #define ASIN 4
68 #define ASINH 5
69 #define ATAN 6
70 #define ATAN2 7
71 #define ATANH 8
72 #define BESSI 9
73 #define BESSJ 10
74 #define BESSK 11
75 #define CEIL 12
76 #define COS 13
77 #define COSH 14
78 #define DBESSI 15
79 #define DBESSJ 16
80 #define DBESSK 17
81 #define DJROOT 18
82 #define EXP 19
83 #define FACT 20
84 #define FLOOR 21
85 #define JROOT 22
86 #define LN 23
87 #define LOG 24
88 #define SIGN 25
89 #define SIN 26
90 #define SINH 27
91 #define SQRT 28
92 #define TAN 29
93 #define TANH 30
95 static FUNC flist[NUMFUNCS] =
97 {ABSVAL,"abs", "x", "absolute value" },
98 {ACOS, "acos", "x", "arccosine, return value in radians" },
99 {ACOSH, "acosh", "x", "inverse hyperbolic cosine" },
100 {ASIN, "asin", "x", "arcsine, return value in radians" },
101 {ASINH, "asinh", "x", "inverse hyperbolic sine" },
102 {ATAN, "atan", "x", "arctangent, return value in radians" },
103 {ATAN2, "atan2", "y,x","arctangent of y/x, return value in radians" },
104 {ATANH, "atanh", "x", "inverse hyperbolic tangent" },
105 {BESSI, "bessi", "m,x","bessel function Im(x)" },
106 {BESSJ, "bessj", "m,x","bessel function Jm(x)" },
107 {BESSK, "bessk", "m,x","bessel function Km(x)" },
108 {CEIL, "ceil", "x", "round up" },
109 {COS, "cos", "x", "cosine, x in radians" },
110 {COSH, "cosh", "x", "hyperbolic cosine" },
111 {DBESSI,"dbessi", "m,x","derivative of bessel function: Im'(x)" },
112 {DBESSJ,"dbessj", "m,x","derivative of bessel function: Jm'(x)" },
113 {DBESSK,"dbessk", "m,x","derivative of bessel function: Km'(x)" },
114 {DJROOT,"djroot", "m,n","nth non-zero root of Jm'(x)" },
115 {EXP, "exp", "x", "e (2.718..) raised to the power of x" },
116 {FACT, "fact", "n", "factorial (n!)" },
117 {FLOOR, "floor", "x", "round down" },
118 {JROOT, "jroot", "m,n","nth non-zero root of Jm(x)" },
119 {LN, "ln", "x", "natural logarithm (base e)" },
120 {LOG, "log", "x", "logarithm to the base 10" },
121 {SIGN, "sgn", "x", "-1 if x<0, 0 if x=0, +1 if x>0" },
122 {SIN, "sin", "x", "sine, x in radians" },
123 {SINH, "sinh", "x", "hyperbolic sine" },
124 {SQRT, "sqrt", "x", "squareroot" },
125 {TAN, "tan", "x", "tangent, x in radians" },
126 {TANH, "tanh", "x", "hyperbolic tangent" }
130 static BOOLEAN func_error(int,int);
131 static int maxfunclen(FUNCPTR);
134 ** print_funclist(FILE *s,char *input,int d)
136 ** Prints a list of the functions
139 int print_funclist(FILE *s,char *input,int d)
142 char line[MAXALEN+MAXFLEN+MAXDLEN+10];
143 int i,j,k,l,n,m1,nc,cw,nr,li,c;
145 m1=maxfunclen(flist)+2;
146 cw=m1+2;
147 if (d)
148 nc=1;
149 else
151 nc=(SCRWIDTH+3)/cw;
152 if (nc<=0)
153 nc=1;
155 nr=(NUMFUNCS+nc-1)/nc;
156 for (i=0;i<nr;i++)
158 li=0;
159 for (j=0;j<nc;j++)
161 k=i+j*nr;
162 if (k>=NUMFUNCS)
163 break;
164 for (l=0;(c=flist[k].name[l])!=EOS;l++)
165 line[li++]=c;
166 line[li++]='(';
167 for (l++,n=l;(c=flist[k].argspec[l-n])!=EOS;l++)
168 line[li++]=c;
169 line[li++]=')';
170 for (l++;l<m1;l++)
171 line[li++]=' ';
172 if (d)
174 for (l=0;l<4;l++)
175 line[li++]=' ';
176 line[li]=EOS;
177 strcat(line,flist[k].desc);
178 li=strlen(line);
180 else
181 if (j<nc-1)
182 for (;l<cw;l++)
183 line[li++]=' ';
185 line[li]=EOS;
186 printf("%s\n",line);
187 if (s==stdin && i!=nr-1 && ((i+3)%NLINES)==0)
189 printf("\nPress <ENTER> for more...\n");
190 printf("%s",PROMPT);
191 input[0]=EOS;
192 fgets(input,MAXINPUT,s);
193 fixup(input);
194 if (input[0]!=EOS)
195 return(1);
196 printf("\n");
199 printf("\n");
200 return(0);
205 ** maxfunclen(FUNCPTR flist)
207 ** returns the length of the longest function name plus arguments
208 ** (used for printing)
212 static int maxfunclen(FUNCPTR flist)
215 int i,len,max;
217 for (max=strlen(flist[0].name)+strlen(flist[0].argspec),i=1;i<NUMFUNCS;i++)
218 if ((len=strlen(flist[i].name)+strlen(flist[i].argspec))>max)
219 max=len;
220 return(max);
224 int func_code(char *s)
227 int i,step,c,count;
229 i=step=NUMFUNCS>>1;
230 count=0;
231 while (1)
233 if (step>1)
234 step>>=1;
235 else
237 count++;
238 if (count>5)
239 break;
241 if (!(c=strcmp(s,flist[i].name)))
242 return(i+1);
243 if (c>0)
245 if (i==NUMFUNCS-1)
246 break;
247 i=i+step;
248 continue;
250 if (i==0)
251 break;
252 i=i-step;
254 return(0);
259 int func_nargs(int code)
262 return((int)((strlen(flist[code-1].argspec)+1)/2));
266 char *func_name(int code)
269 return(flist[code-1].name);
273 BOOLEAN func_eval(int code,double *args,double *ret_val)
276 switch (flist[code-1].id)
278 case ABSVAL:
279 (*ret_val)=fabs(args[0]);
280 return(1);
281 case ACOS:
282 if (args[0]<-1 || args[0]>1)
283 return(func_error(code,0));
284 (*ret_val)=acos(args[0]);
285 return(1);
286 case ACOSH:
287 if (args[0]<1)
288 return(func_error(code,0));
289 (*ret_val)=acosh(args[0]);
290 return(1);
291 case ASIN:
292 if (args[0]<-1 || args[0]>1)
293 return(func_error(code,0));
294 (*ret_val)=asin(args[0]);
295 return(1);
296 case ASINH:
297 (*ret_val)=asinh(args[0]);
298 return(1);
299 case ATAN:
300 (*ret_val)=atan(args[0]);
301 return(1);
302 case ATAN2:
303 (*ret_val)=atan2(args[0],args[1]);
304 return(1);
305 case ATANH:
306 if (args[0]<=-1 || args[0]>=1)
307 return(func_error(code,0));
308 (*ret_val)=atanh(args[0]);
309 return(1);
310 case BESSI:
311 if (args[0]!=((int)args[0]))
312 return(func_error(code,1));
313 (*ret_val)=bessi((int)args[0],args[1]);
314 return(1);
315 case BESSJ:
316 if (args[0]!=((int)args[0]))
317 return(func_error(code,1));
318 (*ret_val)=bessj((int)args[0],args[1]);
319 return(1);
320 case BESSK:
321 if (args[0]!=((int)args[0]))
322 return(func_error(code,1));
323 (*ret_val)=bessk((int)args[0],args[1]);
324 return(1);
325 case CEIL:
326 (*ret_val)=ceil(args[0]);
327 return(1);
328 case COS:
329 (*ret_val)=cos(args[0]);
330 return(1);
331 case COSH:
332 (*ret_val)=cosh(args[0]);
333 return(1);
334 case DBESSI:
335 if (args[0]!=((int)args[0]))
336 return(func_error(code,1));
337 (*ret_val)=dbessi((int)args[0],args[1]);
338 return(1);
339 case DBESSJ:
340 if (args[0]!=((int)args[0]))
341 return(func_error(code,1));
342 (*ret_val)=dbessj((int)args[0],args[1]);
343 return(1);
344 case DBESSK:
345 if (args[0]!=((int)args[0]))
346 return(func_error(code,1));
347 (*ret_val)=dbessk((int)args[0],args[1]);
348 return(1);
349 case DJROOT:
350 if (args[0]!=((int)args[0]))
351 return(func_error(code,1));
352 if (args[1]!=((int)args[1]) || args[1]<1)
353 return(func_error(code,2));
354 (*ret_val)=djroot((int)args[0],(int)args[1]);
355 return(1);
356 case EXP:
357 (*ret_val)=exp(args[0]);
358 return(1);
359 case FACT:
360 if (args[0]<0)
361 return(func_error(code,5));
362 if (args[0]!=((int)args[0]))
363 return(func_error(code,3));
364 (*ret_val)=factorial((int)args[0]);
365 return(1);
366 case FLOOR:
367 (*ret_val)=floor(args[0]);
368 return(1);
369 case JROOT:
370 if (args[0]!=((int)args[0]))
371 return(func_error(code,1));
372 if (args[1]!=((int)args[1]) || args[1]<1)
373 return(func_error(code,2));
374 (*ret_val)=jroot((int)args[0],(int)args[1]);
375 return(1);
376 case LN:
377 if (args[0]<=0)
378 return(func_error(code,4));
379 (*ret_val)=log(args[0]);
380 return(1);
381 case LOG:
382 if (args[0]<=0)
383 return(func_error(code,4));
384 (*ret_val)=log10(args[0]);
385 return(1);
386 case SIGN:
387 (*ret_val)=SGN(args[0]);
388 return(1);
389 case SIN:
390 (*ret_val)=sin(args[0]);
391 return(1);
392 case SINH:
393 (*ret_val)=sinh(args[0]);
394 return(1);
395 case SQRT:
396 if (args[0]<0)
397 return(func_error(code,5));
398 (*ret_val)=sqrt(args[0]);
399 return(1);
400 case TAN:
401 (*ret_val)=tan(args[0]);
402 return(1);
403 case TANH:
404 (*ret_val)=tanh(args[0]);
405 return(1);
407 printf("Unknown function code.\n");
408 return(0);
412 static BOOLEAN func_error(int code,int error)
415 static char *error_code[] = {
416 "argument out of range",
417 "first argument must be an integer",
418 "second argument must be a positive integer",
419 "argument must be an integer",
420 "argument must be positive",
421 "argument must be non-negative",
423 printf("%s: %s.\n",flist[code-1].name,error_code[error]);
424 return(0);