langmath.c

Go to the documentation of this file.
00001 
00002 /*  $Id: langmath.c 1342 2006-05-03 20:03:51Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include <math.h>
00029 
00030 #include "frontier.h"
00031 #include "standard.h"
00032 
00033 #include "error.h"
00034 #include "memory.h"
00035 #include "ops.h"
00036 #include "resources.h"
00037 #include "lang.h"
00038 #include "langinternal.h"
00039 #include "langexternal.h"
00040 #include "langsystem7.h"
00041 #include "tablestructure.h"
00042 #include "kernelverbs.h"
00043 #include "kernelverbdefs.h"
00044 #include "shell.rsrc.h"
00045 #include "timedate.h"
00046 #include "langmath.h"
00047 
00048 #define matherrorlist 269
00049 #define notimplementederror 1
00050 
00051 typedef enum tymathtoken { /*verbs that are processed by langmath.c*/
00052     
00053     minfunc,
00054     
00055     maxfunc,
00056     
00057     sqrtfunc,
00058 
00059     cmathverbs
00060     } tymathtoken;
00061 
00062 static boolean mathfunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) {
00063     
00064     hdltreenode hp1 = hparam1;
00065     tyvaluerecord *v = vreturned;
00066     short errornum = 0;
00067     
00068     setbooleanvalue (false, v); /*by default, math functions return false*/
00069     
00070     switch (token) {
00071     
00072         case minfunc: { /* 2004/12/29 smd */
00073             
00074             tyvaluerecord v1, v2;
00075             tyvaluerecord v1copy, v2copy;
00076             tyvaluerecord * vResult = NULL;
00077             boolean fl = false;
00078             
00079             if (!getreadonlyparamvalue (hp1, 1, &v1))
00080                 break;
00081             
00082             flnextparamislast = true;
00083             
00084             if (!getreadonlyparamvalue (hp1, 2, &v2))
00085                 break;
00086             
00087             if (!copyvaluerecord (v1, &v1copy))  /* so that we don't coerce the original */
00088                 break;
00089             
00090             if (!copyvaluerecord (v2, &v2copy))  /* so that we don't coerce the original */
00091                 break;
00092             
00093             if (!coercetypes (&v1copy, &v2copy))
00094             {
00095                 disposevalues (&v1copy, &v2copy);
00096                 
00097                 break;
00098             }
00099             
00100             switch (v1copy.valuetype) {
00101                 
00102                 case novaluetype: {  /* no test needed, nil is nil*/
00103                     initvalue (v, novaluetype);
00104                     
00105                     fl = true;
00106                     
00107                     break;
00108                     }
00109                 
00110                 case booleanvaluetype: /* if v2 is true, then return v1 (false < true) */
00111                     vResult = v2copy.data.flvalue ? &v1 : &v2;
00112                     
00113                     break;
00114                 
00115                 /* all the rest return the greater of the two values */
00116                 case charvaluetype:
00117                     vResult = ( v1copy.data.chvalue <= v2copy.data.chvalue ) ? &v1 : &v2;
00118                     
00119                     break;
00120                             
00121                 case intvaluetype:
00122                     vResult = ( v1copy.data.intvalue <= v2copy.data.intvalue ) ? &v1 : &v2;
00123                     
00124                     break;
00125                 
00126                 case longvaluetype:
00127                 case ostypevaluetype:
00128                     vResult = ( v1copy.data.longvalue <= v2copy.data.longvalue ) ? &v1 : &v2;
00129                     
00130                     break;
00131                 
00132                 case directionvaluetype:
00133                     vResult = ( (short) v1copy.data.dirvalue <= (short) v2copy.data.dirvalue ) ? &v1 : &v2;
00134                     
00135                     break;
00136                     
00137                 case datevaluetype:
00138                     vResult = timegreaterthan( v2copy.data.datevalue, v1copy.data.datevalue ) ? &v1 : &v2;
00139                     
00140                     break;
00141                 
00142                 case singlevaluetype:
00143                     vResult = ( v1copy.data.singlevalue <= v2copy.data.singlevalue ) ? &v1 : &v2;
00144                     
00145                     break;
00146                 
00147                 case doublevaluetype:
00148                     vResult = ( **v1copy.data.doublevalue <= **v2copy.data.doublevalue ) ? &v1 : &v2;
00149                     
00150                     break;
00151                 
00152                 case stringvaluetype:
00153                     vResult = ( comparehandles( v1copy.data.stringvalue, v2copy.data.stringvalue ) == 1 ) ? &v2 : &v1;
00154                     
00155                     break;
00156                 
00157                 default:
00158                     langerror (comparisonnotpossibleerror);
00159                     
00160                     fl = false; /*operation is not defined*/
00161                     
00162                     break;
00163             } /*switch*/
00164             
00165             if ( vResult != NULL )
00166             {
00167                 if ( copyvaluerecord( *vResult, v ) )
00168                     fl = true;
00169                 
00170                 disposevalues( &v1copy, &v2copy );
00171             }
00172             
00173             return ( fl );
00174         }
00175         
00176         case maxfunc: { /* 2004/12/29 smd */
00177             
00178             tyvaluerecord v1, v2;
00179             tyvaluerecord v1copy, v2copy;
00180             tyvaluerecord * vResult = NULL;
00181             boolean fl = false;
00182             
00183             if (!getreadonlyparamvalue (hp1, 1, &v1))
00184                 break;
00185             
00186             flnextparamislast = true;
00187             
00188             if (!getreadonlyparamvalue (hp1, 2, &v2))
00189                 break;
00190             
00191             if (!copyvaluerecord (v1, &v1copy))  /* so that we don't coerce the original */
00192                 break;
00193             
00194             if (!copyvaluerecord (v2, &v2copy))  /* so that we don't coerce the original */
00195                 break;
00196             
00197             if (!coercetypes (&v1copy, &v2copy))
00198             {
00199                 disposevalues (&v1, &v2);
00200                 
00201                 break;
00202             }
00203             
00204             switch (v1copy.valuetype) {
00205                 
00206                 case novaluetype: {  /* no test needed, nil is nil*/
00207                     initvalue (v, novaluetype);
00208                     
00209                     fl = true;
00210                     
00211                     break;
00212                     }
00213                 
00214                 case booleanvaluetype: /* if v2 is true, then return v1 (false < true) */
00215                     vResult = v1copy.data.flvalue ? &v1 : &v2;
00216                     
00217                     break;
00218                 
00219                 /* all the rest return the greater of the two values */
00220                 case charvaluetype:
00221                     vResult = ( v1copy.data.chvalue >= v2copy.data.chvalue ) ? &v1 : &v2;
00222                     
00223                     break;
00224                             
00225                 case intvaluetype:
00226                     vResult = ( v1copy.data.intvalue >= v2copy.data.intvalue ) ? &v1 : &v2;
00227                     
00228                     break;
00229                 
00230                 case longvaluetype:
00231                 case ostypevaluetype:
00232                     vResult = ( v1copy.data.longvalue >= v2copy.data.longvalue ) ? &v1 : &v2;
00233                     
00234                     break;
00235                 
00236                 case directionvaluetype:
00237                     vResult = ( (short) v1copy.data.dirvalue >= (short) v2copy.data.dirvalue ) ? &v1 : &v2;
00238                     
00239                     break;
00240                     
00241                 case datevaluetype:
00242                     vResult = timegreaterthan( v1copy.data.datevalue, v2copy.data.datevalue ) ? &v1 : &v2;
00243                     
00244                     break;
00245                 
00246                 case singlevaluetype:
00247                     vResult = ( v1copy.data.singlevalue >= v2copy.data.singlevalue ) ? &v1 : &v2;
00248                     
00249                     break;
00250                 
00251                 case doublevaluetype:
00252                     vResult = ( **v1copy.data.doublevalue >= **v2copy.data.doublevalue ) ? &v1 : &v2;
00253                     
00254                     break;
00255                 
00256                 case stringvaluetype:
00257                     vResult = ( comparehandles( v1copy.data.stringvalue, v2copy.data.stringvalue ) != -1 ) ? &v1 : &v2;
00258                     
00259                     break;
00260                 
00261                 default:
00262                     langerror (comparisonnotpossibleerror);
00263                     
00264                     fl = false; /*operation is not defined*/
00265                     
00266                     break;
00267             } /*switch*/
00268             
00269             if ( vResult != NULL )
00270             {
00271                 if ( copyvaluerecord( *vResult, v ) )
00272                     fl = true;
00273                 
00274                 disposevalues( &v1copy, &v2copy );
00275             }
00276             
00277             return ( fl );
00278         }
00279         
00280         case sqrtfunc: { /* 2004/12/29 smd */
00281             
00282             tyvaluerecord v1;
00283             double d;
00284             
00285             flnextparamislast = true;
00286             
00287             if (!getdoubleparam (hp1, 1, &v1))
00288                 break;
00289             
00290             d = sqrt (**v1.data.doublevalue);
00291             
00292             return (setdoublevalue (d, v));
00293             }
00294 
00295         default:
00296             errornum = notimplementederror;
00297             
00298             goto error;
00299         } /*switch*/
00300     
00301     error:
00302     
00303     if (errornum != 0) /*get error string*/
00304         getstringlist (matherrorlist, errornum, bserror);
00305     
00306     return (false);
00307     } /*langmathvalue*/
00308     
00309 
00310 boolean mathinitverbs (void) {
00311     
00312     /*
00313     2004-12-29 smd: new math verbs
00314     */
00315     
00316     return (loadfunctionprocessor (idmathverbs, &mathfunctionvalue));
00317     } /*mathinitverbs*/

Generated on Wed May 31 18:19:52 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6