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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 708 - (show annotations) (download) (as text)
Tue Jun 27 07:34:31 2006 UTC (17 years, 11 months ago) by johnpye
File MIME type: text/x-csrc
File size: 41406 byte(s)
Replaced some references to ascmalloc with ASC_NEW_ARRAY
1 /*
2 * Value Type Implementation
3 * by Tom Epperly
4 * Created: 1/16/90
5 * Version: $Revision: 1.20 $
6 * Version control file: $RCSfile: value_type.c,v $
7 * Date last modified: $Date: 1998/02/05 22:23:36 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
13 * Copyright (C) 1996 Benjamin Andrew Allan
14 *
15 * The Ascend Language Interpreter is free software; you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * The Ascend Language Interpreter is distributed in hope that it will be
21 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the program; if not, write to the Free Software Foundation,
27 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
28 * COPYING.
29 *
30 */
31 #include <math.h>
32 #include <stdarg.h>
33 #include <utilities/ascConfig.h>
34 #include <utilities/ascMalloc.h>
35 #include <utilities/ascPanic.h>
36 #include <general/list.h>
37 #include <general/pool.h>
38 #ifndef FIRSTCHOICE
39 #include <general/hashpjw.h>
40 #endif
41 #include "compiler.h"
42 #include "symtab.h"
43 #include "instance_enum.h"
44 #include "cmpfunc.h"
45 #include "fractions.h"
46 #include "dimen.h"
47 #include "functype.h"
48 #include "func.h"
49 #include "setinstval.h"
50 /* stuf for ListMode */
51 #include "expr_types.h"
52 #include "find.h"
53 #include "value_type.h"
54
55 #ifndef lint
56 static CONST char ValueTypeRCSid[] = "$Id: value_type.c,v 1.20 1998/02/05 22:23:36 ballan Exp $";
57 #endif
58
59 static pool_store_t g_value_pool = NULL;
60 /* A pool_store for value_t elements.
61 * If you can figure out when to reset it, do so.
62 */
63
64 void ValInit(struct value_t *v)
65 {
66 memset((char *)v,0,sizeof(struct value_t));
67 }
68 /*
69 * IVAL(stackvar) should be called on locally allocated
70 * value_t before any other action using them is taken.
71 * When NDEBUG is not defined, it causes the stack memory to be
72 * initialized to 0. Normally it is a do nothing macro.
73 * Proper initialization helps us separate signal from noise in
74 * gdb and purify.
75 */
76
77 #define POOL_ALLOCVALUE ((struct value_t *)(pool_get_element(g_value_pool)))
78 /* get a value */
79 #define POOL_FREEVALUE(p) (pool_free_element(g_value_pool,(void *)(p)))
80 /* return a value_t for reuse */
81 #define POOL_RESET pool_clear_store(g_value_pool)
82 /* reset the pool for next time. only safe after all objects,types killed. */
83
84 #define VP_LEN 2
85 #if (SIZEOF_VOID_P == 8)
86 #define VP_WID 41
87 #else
88 #define VP_WID 42
89 #endif
90 /* retune vpwid if the size of value_t changes dramatically */
91 #define VP_ELT_SIZE (sizeof(struct value_t))
92 #define VP_MORE_ELTS 1
93 /* Number of slots filled if more elements needed.
94 So if the pool grows, it grows by VP_MORE_ELTS*VP_WID elements at a time. */
95 #define VP_MORE_BARS 50
96 /* This is the number of pool bar slots to add during expansion.
97 not all the slots will be filled immediately. */
98
99 /* This function is called at compiler startup time and destroy at shutdown.
100 One could also recall these every time there is a delete all types. */
101 void InitValueManager(void) {
102 if (g_value_pool != NULL ) {
103 Asc_Panic(2, NULL, "ERROR: InitValueManager called twice.\n");
104 }
105 g_value_pool =
106 pool_create_store(VP_LEN, VP_WID, VP_ELT_SIZE, VP_MORE_ELTS, VP_MORE_BARS);
107 if (g_value_pool == NULL) {
108 Asc_Panic(2, NULL, "ERROR: InitValueManager unable to allocate pool.\n");
109 }
110 }
111
112 void DestroyValueManager(void) {
113 if (g_value_pool==NULL) return;
114 pool_destroy_store(g_value_pool);
115 g_value_pool = NULL;
116 }
117
118 void ReportValueManager(FILE *f)
119 {
120 if (g_value_pool==NULL)
121 FPRINTF(f,"ValueManager is empty\n");
122 FPRINTF(f,"ValueManager ");
123 pool_print_store(f,g_value_pool,0);
124 }
125
126 struct value_t CreateRealValue(double value, CONST dim_type *dim,unsigned cv)
127 {
128 struct value_t result;
129 IVAL(result);
130 result.t = real_value;
131 result.constant = cv ? 1:0;
132 result.u.r.value = value;
133 result.u.r.dimp = dim;
134 return result;
135 }
136
137 struct value_t CreateIntegerValue(long int value, unsigned cv)
138 {
139 struct value_t result;
140 IVAL(result);
141 result.t = integer_value;
142 result.constant = cv ? 1:0;
143 result.u.i = value;
144 return result;
145 }
146
147 struct value_t CreateSymbolValue(symchar *sym_ptr, unsigned cv)
148 {
149 struct value_t result;
150 IVAL(result);
151 assert(sym_ptr == NULL || AscFindSymbol(sym_ptr)!=NULL);
152 result.t = symbol_value;
153 result.constant = cv ? 1:0;
154 result.u.sym_ptr = sym_ptr;
155 return result;
156 }
157
158 struct value_t CreateBooleanValue(int truth, unsigned cv)
159 {
160 struct value_t result;
161 IVAL(result);
162 result.t = boolean_value;
163 result.constant = cv;
164 result.u.b = truth ? 1 : 0;
165 return result;
166 }
167
168 struct value_t CreateSetValue(struct set_t *sptr)
169 {
170 struct value_t result;
171 IVAL(result);
172 result.t = set_value;
173 result.constant = 1;
174 result.u.sptr = sptr;
175 return result;
176 }
177
178 struct value_t CreateSetFromList(struct value_t value)
179 {
180 struct value_t result;
181 register struct value_t *vptr;
182 register struct set_t *sptr,*tmp;
183 register struct gl_list_t *list;
184 register unsigned long c,len;
185 IVAL(result);
186 if (value.t == error_value) return value;
187 result.t = set_value;
188 result.constant = 1;
189 if (value.t == list_value){
190 sptr = CreateEmptySet();
191 result.u.sptr = sptr;
192 list = value.u.lvalues;
193 if (gl_length(list)>0){
194 len = gl_length(list);
195 for(c=1;c<=len;c++){
196 vptr = (struct value_t *)gl_fetch(list,c);
197 switch(vptr->t){
198 case integer_value:
199 if (SetKind(sptr)==string_set){
200 result.t = error_value;
201 result.u.t = type_conflict;
202 DestroySet(sptr);
203 return result;
204 }
205 InsertInteger(sptr,vptr->u.i);
206 break;
207 case symbol_value:
208 if (SetKind(sptr)==integer_set){
209 result.t = error_value;
210 result.u.t = type_conflict;
211 DestroySet(sptr);
212 return result;
213 }
214 InsertString(sptr,vptr->u.sym_ptr);
215 break;
216 case set_value:
217 if ((SetKind(sptr)==empty_set)
218 ||(SetKind(sptr)==SetKind(vptr->u.sptr))){
219 tmp = SetUnion(sptr,vptr->u.sptr);
220 DestroySet(sptr);
221 sptr = tmp;
222 result.u.sptr = sptr;
223 }
224 else{
225 DestroySet(sptr);
226 result.t = error_value;
227 result.u.t = type_conflict;
228 return result;
229 }
230 break;
231 default:
232 result.t = error_value;
233 result.u.t = type_conflict;
234 DestroySet(sptr);
235 return result;
236 }
237 }
238 }
239 }
240 else if (value.t == integer_value){
241 sptr = CreateEmptySet();
242 InsertInteger(sptr,value.u.i);
243 result.u.sptr = sptr;
244 }
245 else if (value.t == symbol_value){
246 sptr = CreateEmptySet();
247 InsertString(sptr,value.u.sym_ptr);
248 result.u.sptr = sptr;
249 }
250 else if (value.t == set_value){
251 result.u.sptr = CopySet(value.u.sptr);
252 }
253 else{ /* error */
254 result.t = error_value;
255 result.u.t = type_conflict;
256 }
257 return result;
258 }
259
260 struct value_t CreateOrderedSetFromList(struct value_t value)
261 {
262 struct value_t result;
263 register struct value_t *vptr;
264 register struct set_t *sptr;
265 struct set_t *sval;
266 register struct gl_list_t *list;
267 register unsigned long c,len, sc,slen;
268 IVAL(result);
269
270 assert(ListMode!=0);
271 if (value.t == error_value) {
272 return value;
273 }
274 result.t = set_value;
275 result.constant = 0;
276 if (value.t == list_value){
277 sptr = CreateEmptySet();
278 result.u.sptr = sptr;
279 list = value.u.lvalues;
280 if (list) {
281 len = gl_length(list);
282 for(c=1;c<=len;c++){
283 vptr = (struct value_t *)gl_fetch(list,c); /* a list of value_t's */
284 switch(vptr->t){
285 case integer_value:
286 if (SetKind(sptr)==string_set){
287 result.t = error_value;
288 result.u.t = type_conflict;
289 DestroySet(sptr);
290 return result;
291 }
292 AppendIntegerElement(sptr,vptr->u.i);
293 break;
294 case symbol_value:
295 if (SetKind(sptr)==integer_set){
296 result.t = error_value;
297 result.u.t = type_conflict;
298 DestroySet(sptr);
299 return result;
300 }
301 AppendStringElement(sptr,vptr->u.sym_ptr);
302 break;
303 case set_value:
304 sval = SetValue(*vptr);
305 if (SetKind(sval) == SetKind(sptr) || SetKind(sptr) == empty_set) {
306 if (SetKind(sval) == integer_set) {
307 for (sc = 1, slen = Cardinality(sval); sc <= slen; sc++ ) {
308 AppendIntegerElement(sptr,FetchIntMember(sval,sc));
309 }
310 } else {
311 for (sc = 1, slen = Cardinality(sval); sc <= slen; sc++ ) {
312 AppendStringElement(sptr,FetchStrMember(sval,sc));
313 }
314 }
315 break;
316 }
317 /* fall through: set type mismatch */
318 default:
319 result.t = error_value;
320 result.u.t = type_conflict;
321 DestroySet(sptr);
322 return result;
323 }
324 }
325 }
326 }
327 else if (value.t == integer_value){
328 sptr = CreateEmptySet();
329 AppendIntegerElement(sptr,value.u.i);
330 result.u.sptr = sptr;
331 }
332 else if (value.t == symbol_value){
333 sptr = CreateEmptySet();
334 AppendStringElement(sptr,value.u.sym_ptr);
335 result.u.sptr = sptr;
336 }
337 else if (value.t == set_value){/* error */
338 FPRINTF(ASCERR,"Set values are not allowed (2) in LIST processing\n");
339 FPRINTF(ASCERR,"Please report error in CreateOrderedSetFromList\n");
340 result.t = error_value;
341 result.u.t = type_conflict;
342 }
343 else{ /* error */
344 result.t = error_value;
345 result.u.t = type_conflict;
346 }
347 return result;
348 }
349
350
351 static
352 struct value_t CreateListCopy(struct gl_list_t *l)
353 {
354 struct value_t result,*ptr,*cpy;
355 unsigned long c,len;
356 IVAL(result);
357 result.t = list_value;
358 result.constant = 0;
359 len = gl_length(l);
360 result.u.lvalues = gl_create(len);
361 for(c=1;c<=len;c++){
362 ptr = (struct value_t *)gl_fetch(l,c);
363 cpy = POOL_ALLOCVALUE;
364 IVALPTR(cpy);
365 *cpy = CopyValue(*ptr);
366 gl_append_ptr(result.u.lvalues,(VOIDPTR)cpy);
367 }
368 return result;
369 }
370
371 struct value_t CopyValue(struct value_t value)
372 {
373 switch(value.t){
374 case set_value: return CreateSetValue(CopySet(value.u.sptr));
375 case list_value: return CreateListCopy(value.u.lvalues);
376 default: return value;
377 }
378 }
379
380 struct value_t CreateErrorValue(enum evaluation_error t)
381 {
382 struct value_t result;
383 IVAL(result);
384 result.t = error_value;
385 result.constant = 0;
386 result.u.t = t;
387 return result;
388 }
389
390 struct value_t CreateVacantListValue(void)
391 {
392 struct value_t result;
393 IVAL(result);
394 result.t = list_value;
395 result.constant = 0;
396 result.u.lvalues = gl_create(2L);
397 return result;
398 }
399
400 struct value_t CreateEmptyListValue(void)
401 {
402 struct value_t result;
403 IVAL(result);
404 result.t = list_value;
405 result.constant = 0;
406 result.u.lvalues = gl_create(7L);
407 return result;
408 }
409
410 void AppendToListValue(struct value_t list, struct value_t value)
411 {
412 assert(list.t == list_value);
413 if (value.t == list_value){
414 gl_append_list(list.u.lvalues,value.u.lvalues);
415 gl_destroy(value.u.lvalues);
416 return;
417 }
418 else {
419 struct value_t *ptr;
420 ptr = POOL_ALLOCVALUE;
421 IVALPTR(ptr);
422 *ptr = value;
423 gl_append_ptr(list.u.lvalues,(VOIDPTR)ptr);
424 }
425 }
426
427 /* Do not export this function. Applications needn't be creating
428 * independently allocated values. 3/96 baa. Some idiot will call
429 * it with a ptr to C stack space.
430 * Recursive.
431 */
432 static void DestroyAndFreeValue(struct value_t *value)
433 {
434 switch (value->t){
435 case set_value:
436 if (value->u.sptr!=NULL) DestroySet(value->u.sptr);
437 break;
438 case list_value:
439 if (value->u.lvalues!=NULL){
440 gl_iterate(value->u.lvalues,(void (*)(VOIDPTR))DestroyAndFreeValue);
441 gl_destroy(value->u.lvalues);
442 }
443 break;
444 default:
445 break; /* no action required */
446 }
447 /* value->t = error_value; no point, going in recycle who stomps it. */
448 POOL_FREEVALUE(value);
449 }
450
451 /* see header for this function ! */
452 void DestroyValue(struct value_t *value)
453 {
454 switch (value->t){
455 case set_value:
456 if (value->u.sptr!=NULL) DestroySet(value->u.sptr);
457 value->u.sptr = NULL;
458 break;
459 case list_value:
460 if (value->u.lvalues!=NULL){
461 gl_iterate(value->u.lvalues,(void (*)(VOIDPTR))DestroyAndFreeValue);
462 gl_destroy(value->u.lvalues);
463 }
464 value->u.lvalues=NULL;
465 break;
466 default: break; /* no action required */
467 }
468 value->t = error_value;
469 /* Free not required */
470 }
471
472 static
473 struct value_t DimensionConflict(void)
474 {
475 struct value_t result;
476 IVAL(result);
477 result.t = error_value;
478 result.constant = 0;
479 result.u.t = dimension_conflict;
480 return result;
481 }
482
483 static
484 struct value_t EmptyIntersection(void)
485 {
486 struct value_t result;
487 IVAL(result);
488 result.t = error_value;
489 result.constant = 0;
490 result.u.t = empty_intersection;
491 return result;
492 }
493
494 static
495 struct value_t TypeConflict(void)
496 {
497 struct value_t result;
498 IVAL(result);
499 result.t = error_value;
500 result.constant = 0;
501 result.u.t = type_conflict;
502 return result;
503 }
504
505 static
506 int SetsOkay(struct set_t *set1, struct set_t *set2)
507 {
508 if (SetKind(set1)==empty_set) return 1;
509 if (SetKind(set2)==empty_set) return 1;
510 return SetKind(set1)==SetKind(set2);
511 }
512
513 struct value_t AddValues(struct value_t value1, struct value_t value2)
514 {
515 CONST dim_type *dim;
516 if (value1.t == error_value) return value1;
517 if (value2.t == error_value) return value2;
518 if ( (value1.t == boolean_value) ||
519 (value1.t == list_value) ||
520 (value2.t == boolean_value) ||
521 (value2.t == list_value) ) {
522 return TypeConflict();
523 }
524 if ((value1.t == symbol_value) || (value2.t == symbol_value) ) {
525 #ifdef CATTEST
526 /* do nothing */
527 #else
528 return TypeConflict();
529 #endif
530 }
531 if (value1.t==value2.t){
532 switch(value1.t){
533 case real_value:
534 dim = CheckDimensionsMatch(value1.u.r.dimp,value2.u.r.dimp);
535 if (dim!=NULL) {
536 return CreateRealValue(value1.u.r.value+value2.u.r.value,
537 dim,BothConstantValue(value1,value2));
538 }
539 else return DimensionConflict();
540 case integer_value:
541 return CreateIntegerValue(value1.u.i+value2.u.i,
542 BothConstantValue(value1,value2));
543 #ifdef CATTEST
544 case symbol_value:
545 {
546 int slen;
547 char *str;
548 symchar *sym;
549 if (value1.u.sym_ptr==NULL) {
550 return CreateSymbolValue(value2.u.sym_ptr,
551 BothConstantValue(value1,value2));
552 }
553 if (value2.u.sym_ptr==NULL) {
554 return CreateSymbolValue(value1.u.sym_ptr,
555 BothConstantValue(value1,value2));
556 }
557 slen = strlen(value1.u.sym_ptr) + strlen(value2.u.sym_ptr);
558 str = ASC_NEW_ARRAY(char,slen+1);
559 if (str==NULL) {
560 return TypeConflict(); /* out of memory error */
561 }
562 sprintf(str,"%s%s",value1.u.sym_ptr,value2.u.sym_ptr);
563 sym = AddSymbolL(str,slen);
564 ascfree(str);
565 return CreateSymbolValue(sym, BothConstantValue(value1,value2));
566 }
567 #endif
568 case set_value:
569 if (SetsOkay(value1.u.sptr,value2.u.sptr))
570 return CreateSetValue(SetUnion(value1.u.sptr,value2.u.sptr));
571 else return TypeConflict();
572 default: /*NOTREACHED*/
573 break;
574 }
575 /*NOTREACHED*/
576 }
577 else{
578 if((value1.t==integer_value)&&(value2.t==real_value)){
579 dim = CheckDimensionsMatch(Dimensionless(),value2.u.r.dimp);
580 if (dim!=NULL)
581 return CreateRealValue((double)value1.u.i+value2.u.r.value,dim,
582 BothConstantValue(value1,value2));
583 else return DimensionConflict();
584 }
585 if((value1.t==real_value)&&(value2.t==integer_value)){
586 dim = CheckDimensionsMatch(Dimensionless(),value1.u.r.dimp);
587 if (dim!=NULL)
588 return CreateRealValue(value1.u.r.value+(double)value2.u.i,dim,
589 BothConstantValue(value1,value2));
590 else return DimensionConflict();
591 }
592 return TypeConflict();
593 }
594 /*NOTREACHED*/
595 return TypeConflict();
596 }
597
598 struct value_t SubtractValues(struct value_t value1, struct value_t value2)
599 {
600 CONST dim_type *dim;
601 if (value1.t == error_value) return value1;
602 if (value2.t == error_value) return value2;
603 if ((value1.t == symbol_value)
604 ||(value1.t == boolean_value)
605 ||(value1.t == list_value)||
606 (value2.t == symbol_value)
607 ||(value2.t == boolean_value)
608 ||(value2.t == list_value))
609 return TypeConflict();
610 if (value1.t==value2.t){
611 switch(value1.t){
612 case real_value:
613 dim = CheckDimensionsMatch(value1.u.r.dimp,value2.u.r.dimp);
614 if (dim!=NULL)
615 return CreateRealValue(value1.u.r.value-value2.u.r.value,dim,
616 BothConstantValue(value1,value2));
617 else return DimensionConflict();
618 case integer_value:
619 return CreateIntegerValue(value1.u.i-value2.u.i,
620 BothConstantValue(value1,value2));
621 case set_value:
622 if (SetsOkay(value1.u.sptr,value2.u.sptr))
623 return CreateSetValue(SetDifference(value1.u.sptr,value2.u.sptr));
624 else return TypeConflict();
625 default: /*NOTREACHED*/
626 break;
627 }
628 /*NOTREACHED*/
629 }
630 else{
631 if((value1.t==integer_value)&&(value2.t==real_value)){
632 dim = CheckDimensionsMatch(Dimensionless(),value2.u.r.dimp);
633 if (dim!=NULL)
634 return CreateRealValue((double)value1.u.i-value2.u.r.value,dim,
635 BothConstantValue(value1,value2));
636 else return DimensionConflict();
637 }
638 if((value1.t==real_value)&&(value2.t==integer_value)){
639 dim = CheckDimensionsMatch(Dimensionless(),value1.u.r.dimp);
640 if (dim!=NULL)
641 return CreateRealValue(value1.u.r.value-(double)value2.u.i,dim,
642 BothConstantValue(value1,value2));
643 else return DimensionConflict();
644 }
645 return TypeConflict();
646 }
647 /*NOTREACHED*/
648 return TypeConflict();
649 }
650
651 struct value_t MultiplyValues(struct value_t value1, struct value_t value2)
652 {
653 dim_type dim;
654 if (value1.t == error_value) return value1;
655 if (value2.t == error_value) return value2;
656 if ((value1.t == symbol_value)||
657 (value1.t == boolean_value)||
658 (value1.t == list_value)||
659 (value2.t == symbol_value)||
660 (value2.t == boolean_value)||
661 (value2.t == list_value))
662 return TypeConflict();
663 if (value1.t==value2.t){
664 switch(value1.t){
665 case real_value:
666 dim = AddDimensions(value1.u.r.dimp,value2.u.r.dimp);
667 return CreateRealValue(value1.u.r.value*value2.u.r.value,
668 FindOrAddDimen(&dim),BothConstantValue(value1,value2));
669 case integer_value:
670 return CreateIntegerValue(value1.u.i*value2.u.i,
671 BothConstantValue(value1,value2));
672 case set_value:
673 if (SetsOkay(value1.u.sptr,value2.u.sptr))
674 return CreateSetValue(SetIntersection(value1.u.sptr,value2.u.sptr));
675 else return TypeConflict();
676 default: /*NOTREACHED*/
677 break;
678 }
679 /*NOTREACHED*/
680 }
681 else{
682 if((value1.t==integer_value)&&(value2.t==real_value))
683 return CreateRealValue((double)value1.u.i*value2.u.r.value,
684 value2.u.r.dimp,
685 BothConstantValue(value1,value2));
686 if((value1.t==real_value)&&(value2.t==integer_value))
687 return CreateRealValue(value1.u.r.value*(double)value2.u.i,
688 value1.u.r.dimp,BothConstantValue(value1,value2));
689 return TypeConflict();
690 }
691 /*NOTREACHED*/
692 return TypeConflict();
693 }
694
695 struct value_t DivideValues(struct value_t value1, struct value_t value2)
696 {
697 dim_type dim;
698 if (value1.t == error_value) return value1;
699 if (value2.t == error_value) return value2;
700 if ((value1.t == symbol_value)||
701 (value1.t == boolean_value)||
702 (value1.t == list_value)||
703 (value2.t == symbol_value)||
704 (value2.t == boolean_value)||
705 (value2.t == list_value)||
706 (value1.t == set_value)||
707 (value2.t == set_value))
708 return TypeConflict();
709 if (value1.t==value2.t){
710 switch(value1.t){
711 case real_value:
712 dim = SubDimensions(value1.u.r.dimp,value2.u.r.dimp);
713 return CreateRealValue(value1.u.r.value/value2.u.r.value,
714 FindOrAddDimen(&dim),BothConstantValue(value1,value2));
715 case integer_value:
716 return CreateIntegerValue(value1.u.i/value2.u.i,
717 BothConstantValue(value1,value2));
718 default: /*NOTREACHED*/
719 break;
720 }
721 /*NOTREACHED*/
722 }
723 else{
724 if((value1.t==integer_value)&&(value2.t==real_value)){
725 dim = SubDimensions(Dimensionless(),value2.u.r.dimp);
726 return CreateRealValue((double)value1.u.i/value2.u.r.value,
727 FindOrAddDimen(&dim),BothConstantValue(value1,value2));
728 }
729 if((value1.t==real_value)&&(value2.t==integer_value))
730 return CreateRealValue(value1.u.r.value/(double)value2.u.i,
731 value1.u.r.dimp,BothConstantValue(value1,value2));
732 return TypeConflict();
733 }
734 /*NOTREACHED*/
735 return TypeConflict();
736 }
737
738 /* integer x^y function */
739 static
740 long ipower(long int x, long int y)
741 {
742 register long result=1;
743 if (y==0) return result;
744 if (y>0) {
745 while(y-->0)
746 result *= x;
747 } else {
748 switch (x) {
749 case 1:
750 result=1;
751 break;
752 case -1:
753 result=y%2;
754 if (result) result=-1;
755 else result=1;
756 break;
757 default:
758 result=0;
759 break;
760 }
761 }
762 return result;
763 }
764
765 struct value_t PowerValues(struct value_t value1, struct value_t value2)
766 {
767 dim_type dim;
768 if (value1.t == error_value) return value1;
769 if (value2.t == error_value) return value2;
770 if ((value1.t == symbol_value)||
771 (value1.t == boolean_value)||
772 (value1.t == list_value)||
773 (value2.t == symbol_value)||
774 (value2.t == boolean_value)||
775 (value2.t == list_value)||
776 (value1.t == set_value)||
777 (value2.t == set_value))
778 return TypeConflict();
779 if (value1.t==value2.t){
780 switch(value1.t){
781 case real_value:
782 if ((CheckDimensionsMatch(Dimensionless(),value1.u.r.dimp)==NULL)||
783 (CheckDimensionsMatch(Dimensionless(),value2.u.r.dimp)==NULL))
784 return DimensionConflict();
785 return CreateRealValue(pow(value1.u.r.value,value2.u.r.value),
786 Dimensionless(),BothConstantValue(value1,value2));
787 case integer_value:
788 return CreateIntegerValue(ipower(value1.u.i,value2.u.i),
789 BothConstantValue(value1,value2));
790 default: /*NOTREACHED*/
791 break;
792 }
793 /*NOTREACHED*/
794 }
795 else{
796 if((value1.t==integer_value)&&(value2.t==real_value)){
797 if (CheckDimensionsMatch(Dimensionless(),value2.u.r.dimp)==NULL)
798 return DimensionConflict();
799 return CreateRealValue(pow((double)value1.u.i,value2.u.r.value),
800 Dimensionless(),BothConstantValue(value1,value2));
801 }
802 if((value1.t==real_value)&&(value2.t==integer_value)){
803 dim = ScaleDimensions(value1.u.r.dimp,
804 CreateFraction((short)value2.u.i,1));
805 return CreateRealValue(pow(value1.u.r.value,(double)value2.u.i),
806 FindOrAddDimen(&dim),BothConstantValue(value1,value2));
807 }
808 return TypeConflict();
809 }
810 return TypeConflict();
811 }
812
813 struct value_t CardValues(struct value_t value)
814 {
815 if (value.t==error_value) return value;
816 if (value.t==set_value){
817 return CreateIntegerValue((long)Cardinality(value.u.sptr),1);
818 }
819 else return TypeConflict();
820 }
821
822 #ifndef FIRSTCHOICE
823 /*
824 * next two functions used only if firstchoice not defined
825 */
826 static
827 int IntegerSetHash(CONST struct set_t *sptr)
828 /* Styled after hashpjw */
829 /* this should probably be revisited */
830 {
831 unsigned long c;
832 int sum=0,tsum;
833 CONST unsigned long card = (unsigned long)Cardinality(sptr);
834 assert(SetKind(sptr) == integer_set);
835 for(c = 1L;c <= card;c++){
836 sum = (sum << 4) + FetchIntMember(sptr,c);
837 if ( (tsum = sum & 0xf0000000) ){
838 sum = sum ^ (tsum >> 24);
839 sum = sum ^ tsum;
840 }
841 }
842 return sum;
843 }
844
845 static
846 int StringSetHash(CONST struct set_t *sptr)
847 {
848 int c,sum=0;
849 CONST int card = Cardinality(sptr);
850 assert(SetKind(sptr) == string_set);
851 for(c=1;c <= card;c++){
852 sum += hashpjw(FetchStrMember(sptr,c),ULONG_MAX);
853 }
854 return sum;
855 }
856 #endif /* firstchoice */
857
858
859 struct value_t ChoiceValues(struct value_t value)
860 /* This is where the method of evaluating CHOICE is defined. It is */
861 /* designed to return an arbitrary yet consistent value */
862 {
863 int choice, card;
864 if (value.t==error_value) return value;
865 if (value.t==set_value){
866 card = Cardinality(value.u.sptr);
867 if (card == 0)
868 return CreateErrorValue(empty_choice);
869 switch(SetKind(value.u.sptr)){
870 case integer_set:
871 if (card == 1) {
872 choice = 1;
873 } else {
874 #ifdef FIRSTCHOICE
875 choice = 1;
876 #else
877 choice = (IntegerSetHash(value.u.sptr) % card) + 1;
878 #endif
879 }
880 return CreateIntegerValue(FetchIntMember(value.u.sptr,choice),1);
881 case string_set:
882 if (card == 1) {
883 choice = 1;
884 } else {
885 #ifdef FIRSTCHOICE
886 choice = 1;
887 #else
888 choice = (StringSetHash(value.u.sptr) % card) + 1;
889 #endif
890 }
891 return CreateSymbolValue(FetchStrMember(value.u.sptr,choice),1);
892 default:
893 return CreateErrorValue(empty_choice);
894 }
895 }
896 else return TypeConflict();
897 }
898
899 static
900 struct value_t SumList(struct gl_list_t *l)
901 {
902 struct value_t result,*ptr;
903 unsigned long c,len;
904 IVAL(result);
905 len = gl_length(l);
906 if (len>0){
907 ptr = (struct value_t *)gl_fetch(l,1);
908 result = *ptr;
909 if ((result.t!=integer_value)&&(result.t!=real_value))
910 return TypeConflict();
911 for(c=2;(c<=len)&&(result.t!=error_value);c++){
912 ptr = (struct value_t *)gl_fetch(l,c);
913 if ((ptr->t!=integer_value)&&(ptr->t!=real_value)) {
914 return TypeConflict();
915 }
916 result = AddValues(result,*ptr);
917 }
918 return result;
919 }
920 else return CreateIntegerValue(0L,1); /* sum empty = constant 0 */
921 }
922
923 struct value_t SumValues(struct value_t value)
924 {
925 switch(value.t){
926 case real_value: return value;
927 case integer_value: return value;
928 case list_value:
929 return SumList(value.u.lvalues);
930 case error_value:
931 return value;
932 default:
933 return TypeConflict();
934 }
935 }
936
937 static
938 struct value_t MultiplyList(struct gl_list_t *l)
939 {
940 struct value_t result,*ptr;
941 unsigned long c,len;
942 IVAL(result);
943 len = gl_length(l);
944 if (len>0){
945 ptr = (struct value_t *)gl_fetch(l,1);
946 result = *ptr;
947 if ((result.t!=integer_value)&&(result.t!=real_value))
948 return TypeConflict();
949 for(c=2;(c<=len)&&(result.t!=error_value);c++){
950 ptr = (struct value_t *)gl_fetch(l,c);
951 if ((ptr->t!=integer_value)&&(ptr->t!=real_value)) {
952 return TypeConflict();
953 }
954 result = MultiplyValues(result,*ptr);
955 }
956 return result;
957 }
958 else return CreateIntegerValue(1L,1);
959 }
960
961 struct value_t ProdValues(struct value_t value)
962 {
963 switch(value.t){
964 case real_value: return value;
965 case integer_value: return value;
966 case list_value:
967 return MultiplyList(value.u.lvalues);
968 case error_value:
969 return value;
970 default:
971 return TypeConflict();
972 }
973 }
974
975 static
976 struct value_t UnionList(struct gl_list_t *l)
977 {
978 struct value_t result,*ptr,old;
979 unsigned long c,len;
980 IVAL(result);
981 len = gl_length(l);
982 if(len>0){
983 ptr = (struct value_t *)gl_fetch(l,1);
984 if (ptr->t!=set_value) return TypeConflict();
985 result = CreateSetValue(CopySet(ptr->u.sptr));
986 for(c=2;(c<=len)&&(result.t!=error_value);c++){
987 old = result;
988 ptr = (struct value_t *)gl_fetch(l,c);
989 if (ptr->t!=set_value){
990 DestroyValue(&result);
991 return TypeConflict();
992 }
993 result = AddValues(result,*ptr);
994 DestroyValue(&old);
995 }
996 return result;
997 }
998 else return CreateSetValue(CreateEmptySet());
999 }
1000
1001 struct value_t UnionValues(struct value_t value)
1002 {
1003 switch(value.t){
1004 case error_value: return value;
1005 case set_value:
1006 return CreateSetValue(CopySet(value.u.sptr));
1007 case list_value:
1008 return UnionList(value.u.lvalues);
1009 default:
1010 return TypeConflict();
1011 }
1012 }
1013
1014 static
1015 struct value_t IntersectList(struct gl_list_t *l)
1016 {
1017 struct value_t result,*ptr,old;
1018 unsigned long c,len;
1019 IVAL(result);
1020 len = gl_length(l);
1021 if(len>0){
1022 ptr = (struct value_t *)gl_fetch(l,1);
1023 if (ptr->t!=set_value) return TypeConflict();
1024 result = CreateSetValue(CopySet(ptr->u.sptr));
1025 for(c=2;(c<=len)&&(result.t!=error_value);c++){
1026 old = result;
1027 ptr = (struct value_t *)gl_fetch(l,c);
1028 if (ptr->t!=set_value){
1029 DestroyValue(&result);
1030 return TypeConflict();
1031 }
1032 result = MultiplyValues(result,*ptr);
1033 DestroyValue(&old);
1034 }
1035 return result;
1036 }
1037 else return EmptyIntersection();
1038 }
1039
1040 struct value_t IntersectionValues(struct value_t value)
1041 {
1042 switch(value.t){
1043 case error_value: return value;
1044 case set_value:
1045 return CreateSetValue(CopySet(value.u.sptr));
1046 case list_value:
1047 return IntersectList(value.u.lvalues);
1048 default:
1049 return TypeConflict();
1050 }
1051 }
1052
1053 struct value_t OrValues(struct value_t value1, struct value_t value2)
1054 {
1055 if (value1.t==error_value) return value1;
1056 if (value2.t==error_value) return value2;
1057 if ((value1.t!=boolean_value)||(value2.t!=boolean_value))
1058 return TypeConflict();
1059 return CreateBooleanValue(value1.u.b||value2.u.b,
1060 BothConstantValue(value1,value2));
1061 }
1062
1063 struct value_t AndValues(struct value_t value1, struct value_t value2)
1064 {
1065 if (value1.t==error_value) return value1;
1066 if (value2.t==error_value) return value2;
1067 if ((value1.t!=boolean_value)||(value2.t!=boolean_value))
1068 return TypeConflict();
1069 return CreateBooleanValue(value1.u.b&&value2.u.b,
1070 BothConstantValue(value1,value2));
1071 }
1072
1073 struct value_t InValues(struct value_t value1, struct value_t value2)
1074 {
1075 if (value2.t == error_value) return value2;
1076 if (value2.t!= set_value) return TypeConflict();
1077 switch(value1.t){
1078 case error_value: return value1;
1079 case integer_value:
1080 if (SetKind(value2.u.sptr)==string_set) return TypeConflict();
1081 return CreateBooleanValue(IntMember(value1.u.i,value2.u.sptr),
1082 BothConstantValue(value1,value2));
1083 case symbol_value:
1084 if (SetKind(value2.u.sptr)==integer_set) return TypeConflict();
1085 return CreateBooleanValue(StrMember(value1.u.sym_ptr,value2.u.sptr),
1086 BothConstantValue(value1,value2));
1087 default:
1088 return TypeConflict();
1089 }
1090 }
1091
1092 /* checks for identical values and compatible dimens. wild is compatible
1093 * with anything.
1094 */
1095 static
1096 int EqualReals(struct value_t *value1, struct value_t *value2)
1097 {
1098 return (value1->u.r.value == value2->u.r.value &&
1099 CheckDimensionsMatch(value1->u.r.dimp,value2->u.r.dimp)!=NULL);
1100 }
1101
1102 struct value_t EqualValues(struct value_t value1, struct value_t value2)
1103 {
1104 if (value1.t==error_value) return value1;
1105 if (value2.t==error_value) return value2;
1106 if (value1.t==value2.t){
1107 switch(value1.t){
1108 case real_value:
1109 return CreateBooleanValue(EqualReals(&value1,&value2),
1110 BothConstantValue(value1,value2));
1111 case set_value:
1112 return CreateBooleanValue(SetsEqual(value1.u.sptr,value2.u.sptr),
1113 BothConstantValue(value1,value2));
1114 case integer_value:
1115 return CreateBooleanValue(value1.u.i==value2.u.i,
1116 BothConstantValue(value1,value2));
1117 case symbol_value:
1118 return CreateBooleanValue((value1.u.sym_ptr == value2.u.sym_ptr),
1119 BothConstantValue(value1,value2));
1120 case boolean_value:
1121 return CreateBooleanValue(value1.u.b==value2.u.b,
1122 BothConstantValue(value1,value2));
1123 default:
1124 return TypeConflict();
1125 }
1126 }
1127 else{
1128 if((value1.t==integer_value)&&(value2.t==real_value)){
1129 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1130 return DimensionConflict();
1131 else
1132 return CreateBooleanValue((double)value1.u.i==value2.u.r.value,
1133 BothConstantValue(value1,value2));
1134 }
1135 if((value1.t==real_value)&&(value2.t==integer_value)){
1136 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1137 return DimensionConflict();
1138 else
1139 return CreateBooleanValue(value1.u.r.value==(double)value2.u.i,
1140 BothConstantValue(value1,value2));
1141 }
1142 return TypeConflict();
1143 }
1144 }
1145
1146 struct value_t NotEqualValues(struct value_t value1, struct value_t value2)
1147 {
1148 if (value1.t==error_value) return value1;
1149 if (value2.t==error_value) return value2;
1150 if (value1.t==value2.t){
1151 switch(value1.t){
1152 case real_value:
1153 return CreateBooleanValue(value1.u.r.value!=value2.u.r.value,
1154 BothConstantValue(value1,value2));
1155 case integer_value:
1156 return CreateBooleanValue(value1.u.i!=value2.u.i,
1157 BothConstantValue(value1,value2));
1158 case symbol_value:
1159 return CreateBooleanValue((value1.u.sym_ptr != value2.u.sym_ptr),
1160 BothConstantValue(value1,value2));
1161 default:
1162 return TypeConflict();
1163 }
1164 }
1165 else{
1166 if((value1.t==integer_value)&&(value2.t==real_value)){
1167 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1168 return DimensionConflict();
1169 else
1170 return CreateBooleanValue((double)value1.u.i!=value2.u.r.value,
1171 BothConstantValue(value1,value2));
1172 }
1173 if((value1.t==real_value)&&(value2.t==integer_value)){
1174 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1175 return DimensionConflict();
1176 else
1177 return CreateBooleanValue(value1.u.r.value!=(double)value2.u.i,
1178 BothConstantValue(value1,value2));
1179 }
1180 return TypeConflict();
1181 }
1182 }
1183
1184 struct value_t LessValues(struct value_t value1, struct value_t value2)
1185 {
1186 if (value1.t==error_value) return value1;
1187 if (value2.t==error_value) return value2;
1188 if (value1.t==value2.t){
1189 switch(value1.t){
1190 case real_value:
1191 return CreateBooleanValue(value1.u.r.value<value2.u.r.value,
1192 BothConstantValue(value1,value2));
1193 case integer_value:
1194 return CreateBooleanValue(value1.u.i<value2.u.i,
1195 BothConstantValue(value1,value2));
1196 case symbol_value:
1197 return CreateBooleanValue(CmpSymchar(value1.u.sym_ptr,value2.u.sym_ptr)<0,
1198 BothConstantValue(value1,value2));
1199 default:
1200 return TypeConflict();
1201 }
1202 }
1203 else{
1204 if((value1.t==integer_value)&&(value2.t==real_value)){
1205 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1206 return DimensionConflict();
1207 else
1208 return CreateBooleanValue((double)value1.u.i<value2.u.r.value,
1209 BothConstantValue(value1,value2));
1210 }
1211 if((value1.t==real_value)&&(value2.t==integer_value)){
1212 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1213 return DimensionConflict();
1214 else
1215 return CreateBooleanValue(value1.u.r.value<(double)value2.u.i,
1216 BothConstantValue(value1,value2));
1217 }
1218 return TypeConflict();
1219 }
1220 }
1221
1222 struct value_t LessEqValues(struct value_t value1, struct value_t value2)
1223 {
1224 if (value1.t==error_value) return value1;
1225 if (value2.t==error_value) return value2;
1226 if (value1.t==value2.t){
1227 switch(value1.t){
1228 case real_value:
1229 return CreateBooleanValue(value1.u.r.value<=value2.u.r.value,
1230 BothConstantValue(value1,value2));
1231 case integer_value:
1232 return CreateBooleanValue(value1.u.i<=value2.u.i,
1233 BothConstantValue(value1,value2));
1234 case symbol_value:
1235 return CreateBooleanValue(CmpSymchar(value1.u.sym_ptr,
1236 value2.u.sym_ptr) <= 0,
1237 BothConstantValue(value1,value2));
1238 default:
1239 return TypeConflict();
1240 }
1241 }
1242 else{
1243 if((value1.t==integer_value)&&(value2.t==real_value)){
1244 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1245 return DimensionConflict();
1246 else
1247 return CreateBooleanValue((double)value1.u.i<=value2.u.r.value,
1248 BothConstantValue(value1,value2));
1249 }
1250 if((value1.t==real_value)&&(value2.t==integer_value)){
1251 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1252 return DimensionConflict();
1253 else
1254 return CreateBooleanValue(value1.u.r.value<=(double)value2.u.i,
1255 BothConstantValue(value1,value2));
1256 }
1257 return TypeConflict();
1258 }
1259 }
1260
1261 struct value_t GreaterValues(struct value_t value1, struct value_t value2)
1262 {
1263 if (value1.t==error_value) return value1;
1264 if (value2.t==error_value) return value2;
1265 if (value1.t==value2.t){
1266 switch(value1.t){
1267 case real_value:
1268 return CreateBooleanValue(value1.u.r.value>value2.u.r.value,
1269 BothConstantValue(value1,value2));
1270 case integer_value:
1271 return CreateBooleanValue(value1.u.i>value2.u.i,
1272 BothConstantValue(value1,value2));
1273 case symbol_value:
1274 return CreateBooleanValue(CmpSymchar(value1.u.sym_ptr,value2.u.sym_ptr)>0,
1275 BothConstantValue(value1,value2));
1276 default:
1277 return TypeConflict();
1278 }
1279 }
1280 else{
1281 if((value1.t==integer_value)&&(value2.t==real_value)){
1282 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1283 return DimensionConflict();
1284 else
1285 return CreateBooleanValue((double)value1.u.i>value2.u.r.value,
1286 BothConstantValue(value1,value2));
1287 }
1288 if((value1.t==real_value)&&(value2.t==integer_value)){
1289 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1290 return DimensionConflict();
1291 else
1292 return CreateBooleanValue(value1.u.r.value>(double)value2.u.i,
1293 BothConstantValue(value1,value2));
1294 }
1295 return TypeConflict();
1296 }
1297 }
1298
1299
1300 struct value_t GreaterEqValues(struct value_t value1, struct value_t value2)
1301 {
1302 if (value1.t==error_value) return value1;
1303 if (value2.t==error_value) return value2;
1304 if (value1.t==value2.t){
1305 switch(value1.t){
1306 case real_value:
1307 return CreateBooleanValue(value1.u.r.value>=value2.u.r.value,
1308 BothConstantValue(value1,value2));
1309 case integer_value:
1310 return CreateBooleanValue(value1.u.i>=value2.u.i,
1311 BothConstantValue(value1,value2));
1312 case symbol_value:
1313 return CreateBooleanValue(CmpSymchar(value1.u.sym_ptr,
1314 value2.u.sym_ptr) >= 0,
1315 BothConstantValue(value1,value2));
1316 default:
1317 return TypeConflict();
1318 }
1319 }
1320 else{
1321 if((value1.t==integer_value)&&(value2.t==real_value)){
1322 if (CheckDimensionsMatch(value2.u.r.dimp,Dimensionless())==NULL)
1323 return DimensionConflict();
1324 else
1325 return CreateBooleanValue((double)value1.u.i>=value2.u.r.value,
1326 BothConstantValue(value1,value2));
1327 }
1328 if((value1.t==real_value)&&(value2.t==integer_value)){
1329 if (CheckDimensionsMatch(value1.u.r.dimp,Dimensionless())==NULL)
1330 return DimensionConflict();
1331 else
1332 return CreateBooleanValue(value1.u.r.value>=(double)value2.u.i,
1333 BothConstantValue(value1,value2));
1334 }
1335 return TypeConflict();
1336 }
1337 }
1338
1339 struct value_t NegateValue(struct value_t value)
1340 {
1341 switch(value.t){
1342 case error_value: return value;
1343 case integer_value: return CreateIntegerValue(-value.u.i,
1344 IsConstantValue(value));
1345 case real_value: return CreateRealValue(-value.u.r.value,value.u.r.dimp,
1346 IsConstantValue(value));
1347 default:
1348 return TypeConflict();
1349 }
1350 }
1351
1352 struct value_t NotValue(struct value_t value)
1353 {
1354 switch(value.t){
1355 case error_value: return value;
1356 case boolean_value: return CreateBooleanValue(!value.u.b,
1357 IsConstantValue(value));
1358 default:
1359 return TypeConflict();
1360 }
1361 }
1362
1363 /* original. delete when smoke clears.
1364 struct value_t ApplyFunction(struct value_t value, CONST struct Func *f)
1365 {
1366 CONST dim_type *dim;
1367 switch(value.t){
1368 case error_value: return value;
1369 case integer_value:
1370 return CreateRealValue(FuncEval(f,(double)IntegerValue(value))
1371 ,Dimensionless(),IsConstantValue(value));
1372 case real_value:
1373 dim = CheckDimensionsMatch(Dimensionless(),value.u.r.dimp);
1374 if (dim==NULL)
1375 return DimensionConflict();
1376 else
1377 return CreateRealValue(FuncEval(f,RealValue(value)),Dimensionless(),
1378 IsConstantValue(value));
1379 default:
1380 return TypeConflict();
1381 }
1382 }
1383 */
1384 struct value_t ApplyFunction(struct value_t value, CONST struct Func *f)
1385 {
1386 CONST dim_type *dim;
1387 dim_type sdim;
1388 switch(value.t){
1389 case error_value: return value;
1390 case integer_value:
1391 return CreateRealValue(FuncEval(f,(double)IntegerValue(value)),
1392 Dimensionless(),IsConstantValue(value));
1393 case real_value:
1394 dim = CheckDimensionsMatch(FuncDimens(f),value.u.r.dimp);
1395 if (dim==NULL)
1396 return DimensionConflict();
1397 else
1398 switch (FuncId(f)) {
1399 case F_LOG10:
1400 case F_LN:
1401 case F_EXP:
1402 #ifdef HAVE_ERF
1403 case F_ERF:
1404 #endif
1405 case F_LNM:
1406 case F_SIN:
1407 case F_COS:
1408 case F_TAN:
1409 case F_SINH:
1410 case F_COSH:
1411 case F_TANH:
1412 case F_ARCSINH:
1413 case F_ARCCOSH:
1414 case F_ARCTANH:
1415 return CreateRealValue(FuncEval(f,RealValue(value)),
1416 Dimensionless(),IsConstantValue(value));
1417 case F_SQRT:
1418 if (OddDimension(dim))
1419 return DimensionConflict();
1420 else {
1421 CONST dim_type *dp=HalfDimension(dim,FALSE);
1422 return CreateRealValue(FuncEval(f,RealValue(value)), dp,
1423 IsConstantValue(value));
1424 }
1425 case F_CBRT:
1426 if (NonCubicDimension(dim))
1427 return DimensionConflict();
1428 else {
1429 CONST dim_type *dp=ThirdDimension(dim,FALSE);
1430 return CreateRealValue(FuncEval(f,RealValue(value)), dp,
1431 IsConstantValue(value));
1432 }
1433 case F_ARCSIN:
1434 case F_ARCCOS:
1435 case F_ARCTAN:
1436 return CreateRealValue(FuncEval(f,RealValue(value)),
1437 TrigDimension(),IsConstantValue(value));
1438 case F_SQR:
1439 sdim=AddDimensions(dim,dim);
1440 return CreateRealValue(FuncEval(f,RealValue(value)),
1441 FindOrAddDimen(&sdim),IsConstantValue(value));
1442 case F_ABS:
1443 case F_HOLD:
1444 return CreateRealValue(FuncEval(f,RealValue(value)),
1445 dim,IsConstantValue(value));
1446 default:
1447 return TypeConflict();
1448 } /* end func type */
1449 default:
1450 return TypeConflict();
1451 } /* end value type */
1452 }
1453

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