00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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 {
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);
00069
00070 switch (token) {
00071
00072 case minfunc: {
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))
00088 break;
00089
00090 if (!copyvaluerecord (v2, &v2copy))
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: {
00103 initvalue (v, novaluetype);
00104
00105 fl = true;
00106
00107 break;
00108 }
00109
00110 case booleanvaluetype:
00111 vResult = v2copy.data.flvalue ? &v1 : &v2;
00112
00113 break;
00114
00115
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;
00161
00162 break;
00163 }
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: {
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))
00192 break;
00193
00194 if (!copyvaluerecord (v2, &v2copy))
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: {
00207 initvalue (v, novaluetype);
00208
00209 fl = true;
00210
00211 break;
00212 }
00213
00214 case booleanvaluetype:
00215 vResult = v1copy.data.flvalue ? &v1 : &v2;
00216
00217 break;
00218
00219
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;
00265
00266 break;
00267 }
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: {
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 }
00300
00301 error:
00302
00303 if (errornum != 0)
00304 getstringlist (matherrorlist, errornum, bserror);
00305
00306 return (false);
00307 }
00308
00309
00310 boolean mathinitverbs (void) {
00311
00312
00313
00314
00315
00316 return (loadfunctionprocessor (idmathverbs, &mathfunctionvalue));
00317 }