/[ascend]/trunk/base/generic/compiler/dimen.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/dimen.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 500 - (show annotations) (download) (as text)
Tue Apr 18 11:55:12 2006 UTC (15 years, 7 months ago) by johnpye
File MIME type: text/x-csrc
File size: 11622 byte(s)
Reduced some runtime debug messages from Python and C++ and base/generic/compiler/type_descio.c.
Fixed up support for GCC Visibility and add SCons 'sniffer' for this.
Fixed a bug with 'fileopenpath' in PyGTK interface (File->Open location is remembered from last time).
Fixed a bug with missing includes in C++.
1 /*
2 * Dimension implementation routines
3 * by Tom Epperly
4 * Part of Ascend
5 * Version: $Revision: 1.9 $
6 * Version control file: $RCSfile: dimen.c,v $
7 * Date last modified: $Date: 1997/10/28 19:20:32 $
8 * Last modified by: $Author: mthomas $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
13 *
14 * The Ascend Language Interpreter is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The Ascend Language Interpreter is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 *
29 */
30
31 #include <utilities/ascConfig.h>
32 #include "compiler.h"
33 #include <utilities/ascPanic.h>
34 #include <utilities/ascMalloc.h>
35 #include <general/list.h>
36 #include "fractions.h"
37 #include "dimen.h"
38 #include <general/mathmacros.h>
39
40 struct gl_list_t *g_dimen_list;
41 dim_type *g_wild_dimen,*g_trig_dimen,*g_dimensionless;
42 #ifndef lint
43 static CONST char DimenID[] = "$Id: dimen.c,v 1.9 1997/10/28 19:20:32 mthomas Exp $";
44 #endif
45
46 #define WILD(d) ((d)->wild & DIM_WILD)
47 /* test a DIMENSION pointer for being wild or not */
48
49 char *DimNames[NUM_DIMENS]={
50 /* keep this structure current with defines in dimen.h */
51 "M",
52 "Q",
53 "L",
54 "T",
55 "TMP",
56 "C",
57 "E",
58 "LUM",
59 "P",
60 "S"
61 };
62
63
64 void InitDimenList(void)
65 {
66 /* FPRINTF(ASCERR,"INITIALISING DIMENSION LIST\n"); */
67
68 g_dimen_list = gl_create(200L);
69 AssertMemory(g_dimen_list);
70 g_wild_dimen = (dim_type *)ascmalloc((unsigned)sizeof(dim_type));
71 AssertAllocatedMemory(g_wild_dimen,sizeof(dim_type));
72 g_trig_dimen = (dim_type *)ascmalloc((unsigned)sizeof(dim_type));
73 AssertAllocatedMemory(g_trig_dimen,sizeof(dim_type));
74 g_dimensionless = (dim_type *)ascmalloc((unsigned)sizeof(dim_type));
75 AssertAllocatedMemory(g_dimensionless,sizeof(dim_type));
76 assert((g_wild_dimen!=NULL)&&(g_dimensionless!=NULL)&&(g_trig_dimen!=NULL));
77 ClearDimensions(g_wild_dimen);
78 ClearDimensions(g_trig_dimen);
79 ClearDimensions(g_dimensionless);
80 g_dimensionless->wild=0;
81 g_wild_dimen->wild = DIM_WILD;
82 g_trig_dimen->wild = 0;
83 SetDimFraction(*g_trig_dimen,D_PLANE_ANGLE,
84 CreateFraction((FRACPART)1,(FRACPART)1));
85 gl_insert_sorted(g_dimen_list,g_dimensionless,(CmpFunc)CmpDimen);
86 gl_insert_sorted(g_dimen_list,g_wild_dimen,(CmpFunc)CmpDimen);
87 gl_insert_sorted(g_dimen_list,g_trig_dimen,(CmpFunc)CmpDimen);
88 }
89
90 void DestroyDimenList(void)
91 {
92 gl_free_and_destroy(g_dimen_list);
93 g_wild_dimen = g_dimensionless = NULL;
94 }
95
96 int IsWild(CONST dim_type *d)
97 {
98 if (d != NULL) {
99 return (WILD(d));
100 } else {
101 FPRINTF(ASCERR,"IsWild called on NULL dimension pointer\n");
102 return 1;
103 }
104 }
105
106 int OddDimension(CONST dim_type *dimp)
107 {
108 int i;
109 if (!dimp || IsWild(dimp)) return 1;
110 for (i=0;i<NUM_DIMENS;i++)
111 if (Denominator(GetDimFraction(*dimp,i))!=1 ||
112 (Numerator(GetDimFraction(*dimp,i))%2) )
113 return 1;
114 return 0;
115 }
116
117 /* return 1 if fractional, null or wild, 0 otherwise */
118 static int FractionalDimension(CONST dim_type *dimp)
119 {
120 int i;
121 if (!dimp || IsWild(dimp)) return 1;
122 for (i=0;i<NUM_DIMENS;i++)
123 if (Denominator(GetDimFraction(*dimp,i))!=1) return 1;
124 return 0;
125 }
126
127 int NonCubicDimension(CONST dim_type *dimp)
128 {
129 int i;
130 if (!dimp || IsWild(dimp)) return 1;
131 for (i=0;i<NUM_DIMENS;i++)
132 if (Denominator(GetDimFraction(*dimp,i))!=1 ||
133 (Numerator(GetDimFraction(*dimp,i))%3) )
134 return 1;
135 return 0;
136 }
137
138 void CopyDimensions(CONST dim_type *src, dim_type *dest)
139 {
140 *dest = *src;
141 }
142
143 CONST dim_type *SquareDimension(CONST dim_type *dim, int check)
144 {
145 if (!dim) return NULL;
146 if (IsWild(dim)) return WildDimension();
147 if (check && FractionalDimension(dim)) return NULL;
148 else {
149 dim_type d;
150 struct fraction sqr=CreateFraction((FRACPART)2,(FRACPART)1);
151 d=ScaleDimensions(dim,sqr);
152 return (FindOrAddDimen(&d));
153 }
154 }
155
156 CONST dim_type *HalfDimension(CONST dim_type *dim, int check)
157 {
158 if (!dim) return NULL;
159 if (IsWild(dim)) return WildDimension();
160 if (check && OddDimension(dim)) return NULL;
161 else {
162 dim_type d;
163 struct fraction half=CreateFraction((FRACPART)1,(FRACPART)2);
164 d=ScaleDimensions(dim,half);
165 return (FindOrAddDimen(&d));
166 }
167 }
168
169 CONST dim_type *CubeDimension(CONST dim_type *dim, int check)
170 {
171 if (!dim) return NULL;
172 if (IsWild(dim)) return WildDimension();
173 if (check && FractionalDimension(dim)) return NULL;
174 else {
175 dim_type d;
176 struct fraction cub=CreateFraction((FRACPART)3,(FRACPART)1);
177 d=ScaleDimensions(dim,cub);
178 return (FindOrAddDimen(&d));
179 }
180 }
181
182 static FRACPART topmax(CONST dim_type *dim) {
183 int i;
184 FRACPART biggest = 0;
185 for (i=0;i<NUM_DIMENS;i++) {
186 biggest = MAX(ABS(Numerator(GetDimFraction(*dim,i))),biggest);
187 }
188 return biggest;
189 }
190
191 CONST dim_type *PowDimension(long mult, CONST dim_type *dim, int check)
192 {
193 if (!dim) return NULL;
194 if (IsWild(dim)) return dim;
195 if (dim==Dimensionless()) return dim;
196 if (check && FractionalDimension(dim)) return NULL;
197 if ((long)FRACMAX < mult*topmax(dim)) return NULL;
198 else {
199 dim_type d;
200 struct fraction new;
201 new = CreateFraction((FRACPART)mult,(FRACPART)1);
202 d = ScaleDimensions(dim,new);
203 return (FindOrAddDimen(&d));
204 }
205 }
206
207 CONST dim_type *ThirdDimension(CONST dim_type *dim, int check)
208 {
209 if (!dim) return NULL;
210 if (IsWild(dim)) return WildDimension();
211 if (check && NonCubicDimension(dim)) return NULL;
212 else {
213 dim_type d;
214 struct fraction third=CreateFraction((FRACPART)1,(FRACPART)3);
215 d=ScaleDimensions(dim,third);
216 return (FindOrAddDimen(&d));
217 }
218 }
219
220 void SetWild(dim_type *dim)
221 {
222 assert(dim!=NULL);
223 dim->wild=DIM_WILD;
224 }
225
226 int SameDimen(CONST dim_type *d1, CONST dim_type *d2)
227 {
228 assert(d1!=NULL);
229 assert(d2!=NULL);
230
231 if (d1==d2 || (WILD(d1) && WILD(d2)) ) return 1;
232 /* same pointer or both wild return now */
233
234 if ( WILD(d1) || WILD(d2) ) return 0;
235 /* one is wild, other not, so punt */
236
237 return ( memcmp((char *)d1->f,(char *)d2->f,
238 (sizeof(struct fraction)*NUM_DIMENS)) ==0 );
239 }
240
241 int CmpDimen(CONST dim_type *d1, CONST dim_type *d2)
242 {
243 register unsigned c;
244 register int i;
245 assert(d1!=NULL);
246 assert(d2!=NULL);
247 if (WILD(d1)) {
248 if (WILD(d2)) {
249 return 0;
250 } else {
251 return -1;
252 }
253 }
254 if (WILD(d2)) { return 1; }
255 for(c=0;c<NUM_DIMENS;c++) {
256 i = CmpF( GetDimFraction(*d1,c), GetDimFraction(*d2,c) );
257 if (i<0) {
258 return -1;
259 } else {
260 if (i>0) {
261 return 1;
262 }
263 /* else continue to next dimen */
264 }
265 }
266 return 0;
267 }
268
269 void ClearDimensions(dim_type *d)
270 {
271 register unsigned c;
272 struct fraction f;
273 assert(d!=NULL);
274 f = CreateFraction((FRACPART)0,(FRACPART)1);
275 d->wild = 0;
276 for(c=0;c<NUM_DIMENS;c++)
277 SetDimFraction(*d,c,f);
278 }
279
280 CONST dim_type *Dimensionless(void)
281 {
282 AssertAllocatedMemory(g_dimensionless,sizeof(dim_type));
283 return g_dimensionless;
284 }
285
286 CONST dim_type *TrigDimension(void)
287 {
288 AssertAllocatedMemory(g_trig_dimen,sizeof(dim_type));
289 return g_trig_dimen;
290 }
291
292 CONST dim_type *WildDimension(void)
293 {
294 AssertAllocatedMemory(g_wild_dimen,sizeof(dim_type));
295 return g_wild_dimen;
296 }
297
298 static
299 dim_type *CopyDimen(register CONST dim_type *d)
300 {
301 register dim_type *result;
302 assert(d!=NULL);
303 result = (dim_type *)ascmalloc((unsigned)sizeof(dim_type));
304 ascbcopy((char *)d,(char *)result,sizeof(dim_type));
305 AssertAllocatedMemory(result,sizeof(dim_type));
306 return result;
307 }
308
309 CONST dim_type *FindOrAddDimen(CONST dim_type *d)
310 {
311 register unsigned long place;
312 register dim_type *result;
313 if ((place=gl_search(g_dimen_list,d,(CmpFunc)CmpDimen))!=0){
314 result = gl_fetch(g_dimen_list,place);
315 }
316 else {
317 result = CopyDimen(d);
318 gl_insert_sorted(g_dimen_list,result,(CmpFunc)CmpDimen);
319 }
320 AssertAllocatedMemory(result,sizeof(dim_type));
321 return result;
322 }
323
324 dim_type AddDimensions(CONST dim_type *d1, CONST dim_type *d2)
325 {
326 register unsigned c;
327 dim_type result;
328 ClearDimensions(&result);
329 if (WILD(d1)||WILD(d2)) {
330 result.wild = DIM_WILD;
331 } else {
332 for(c=0;c<NUM_DIMENS;c++) {
333 SetDimFraction(result,c,
334 AddF(GetDimFraction(*d1,c),GetDimFraction(*d2,c)));
335 }
336 }
337 return result;
338 }
339
340 CONST dim_type *SumDimensions(CONST dim_type *d1, CONST dim_type *d2,int check)
341 {
342 register unsigned c;
343 dim_type result;
344 if (check && (FractionalDimension(d1) || FractionalDimension(d2)) ) {
345 return NULL;
346 }
347 ClearDimensions(&result);
348 if (WILD(d1)||WILD(d2)) {
349 return WildDimension();
350 } else {
351 for(c=0;c<NUM_DIMENS;c++) {
352 SetDimFraction(result,c,
353 AddF(GetDimFraction(*d1,c),GetDimFraction(*d2,c)));
354 }
355 }
356 return (FindOrAddDimen(&result));
357 }
358
359 dim_type SubDimensions(CONST dim_type *d1, CONST dim_type *d2)
360 {
361 register unsigned c;
362 dim_type result;
363 ClearDimensions(&result);
364 if (WILD(d1)||WILD(d2)) {
365 result.wild = DIM_WILD;
366 } else {
367 for(c=0;c<NUM_DIMENS;c++) {
368 SetDimFraction(result,c,
369 SubF(GetDimFraction(*d1,c),GetDimFraction(*d2,c)));
370 }
371 }
372 return result;
373 }
374
375 CONST dim_type *DiffDimensions(CONST dim_type *d1,
376 CONST dim_type *d2,
377 int check)
378 {
379 register unsigned c;
380 dim_type result;
381 if (check && (FractionalDimension(d1) || FractionalDimension(d2)) ){
382 return NULL;
383 }
384 ClearDimensions(&result);
385 if (WILD(d1)||WILD(d2)) {
386 return WildDimension();
387 } else {
388 for(c=0;c<NUM_DIMENS;c++) {
389 SetDimFraction(result,c,
390 SubF(GetDimFraction(*d1,c),GetDimFraction(*d2,c)));
391 }
392 }
393 return (FindOrAddDimen(&result));
394 }
395
396 dim_type ScaleDimensions(CONST dim_type *dim, struct fraction frac)
397 {
398 dim_type result;
399 register unsigned c;
400 result = *dim;
401 if (result.wild & DIM_WILD) return result;
402 for(c=0;c<NUM_DIMENS;c++) {
403 SetDimFraction(result,c,MultF(frac,GetDimFraction(*dim,c)));
404 }
405 return result;
406 }
407
408 void PrintDimen(FILE *file, CONST dim_type *dim)
409 {
410 int printed;
411 if (WILD(dim)) {
412 FPRINTF(file,"wild");
413 } else {
414 int i;
415 printed = 0;
416 for (i=0;i<NUM_DIMENS; i++) {
417 if (Numerator(dim->f[i])) {
418 FPRINTF(file,"%d/%d%s ",Numerator(dim->f[i]),Denominator(dim->f[i]),
419 DimName(i));
420 printed = 1;
421 }
422 }
423 if (printed == 0) FPRINTF(file,"dimensionless");
424 }
425 }
426
427 void DumpDimens(FILE *file)
428 {
429 register unsigned long c,len;
430 len = gl_length(g_dimen_list);
431 FPRINTF(file,"Dimensions dump\n");
432 for(c=1;c<=len;c++) {
433 PrintDimen(file,(dim_type *)gl_fetch(g_dimen_list,c));
434 PUTC('\n',file);
435 }
436 }
437
438 CONST dim_type *CheckDimensionsMatch(CONST dim_type *d1, CONST dim_type *d2)
439 {
440 if (WILD(d1)) return d2;
441 if (WILD(d2)||d1 == d2) return d1;
442 if (CmpDimen(d1,d2)==0) return d1;
443 return NULL;
444 }
445
446 void ParseDim(dim_type *dim, CONST char *c)
447 {
448 int i;
449 assert((dim!=NULL)&&(c!=NULL));
450 ClearDimensions(dim);
451 for( i=0; i<NUM_DIMENS && strcmp(c,DimNames[i]); i++ ) ;
452 if( i>=NUM_DIMENS ) FPRINTF(ASCERR,"Dimension %s unknown.\n",c);
453 else SetDimFraction(*dim,i,CreateFraction((FRACPART)1,(FRACPART)1));
454 }
455
456 char *DimName(CONST int ndx)
457 {
458 if( ndx >= 0 && ndx < NUM_DIMENS )
459 return( DimNames[ndx] );
460 else
461 return NULL;
462 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22