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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 92 - (show annotations) (download) (as text)
Wed Dec 7 16:30:13 2005 UTC (18 years, 6 months ago) by johnpye
File MIME type: text/x-csrc
File size: 33984 byte(s)
Restored a commented-out function which is needed by standard FC4 autotools build
1 /*
2 * Evaluation Routines
3 * by Tom Epperly
4 * Created: 1/16/90
5 * Version: $Revision: 1.23 $
6 * Version control file: $RCSfile: evaluate.c,v $
7 * Date last modified: $Date: 1998/03/17 22:08:30 $
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 *
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 <stdio.h>
32 #include <assert.h>
33 #include <stdarg.h>
34 #include "utilities/ascConfig.h"
35 #include "utilities/ascMalloc.h"
36 #include "utilities/ascPanic.h"
37 #include "general/dstring.h"
38 #include "general/list.h"
39 #include "compiler/compiler.h"
40 #include "compiler/fractions.h"
41 #include "compiler/dimen.h"
42 #include "compiler/functype.h"
43 #include "compiler/types.h"
44 #include "compiler/setinstval.h"
45 #include "compiler/value_type.h"
46 #include "compiler/name.h"
47 #include "compiler/temp.h"
48 #include "compiler/sets.h"
49 #include "compiler/exprs.h"
50 #include "compiler/find.h"
51 #include "compiler/exprio.h"
52 #include "compiler/evaluate.h"
53
54 #ifndef lint
55 static CONST char EvaluationRoutineRCSid[] = "$Id: evaluate.c,v 1.23 1998/03/17 22:08:30 ballan Exp $";
56 #endif
57
58 static struct gl_list_t *g_names_needed = NULL;
59 /* global var so we are not passing nlist everywhere
60 * that we used to pass *EvaluateName.
61 */
62 #define GNN g_names_needed
63
64 /*********************************************************************\
65 Support Evaluation Routines -- stacks.
66 small, fast, and local. Do not export. BAA. 2/96
67 changed from longs to ints for size and capacity,
68 particularly because expression stacks just don't get that deep.
69 \*********************************************************************/
70 struct stack_t {
71 struct value_t *ptr; /* data pointer */
72 unsigned capacity; /* length of data */
73 unsigned long size; /* pointer while recycled and data while in use */
74 };
75
76 #define SMALLOC(x) x=(struct stack_t *)ascmalloc(sizeof(struct stack_t));
77 #define DMALLOC(x,n) x\
78 =(struct value_t *)ascmalloc((unsigned)n*\
79 (unsigned)sizeof(struct value_t))
80
81 static struct stack_t *AllocStack(unsigned int capacity)
82 {
83 struct stack_t *result;
84 SMALLOC(result);
85 result->size =0;
86 DMALLOC(result->ptr,capacity);
87 result->capacity = capacity;
88 return result;
89 }
90
91 static void DeAllocStack(struct stack_t *stack)
92 {
93 if (stack!=NULL){
94 ascfree((char *)stack->ptr);
95 stack->ptr = NULL;
96 ascfree((char *)stack);
97 }
98 }
99
100 #define RECYCLESTACKSIZE 20 /* largest stack we will attempt to recycle */
101 static struct stack_t * g_recycle_expreval_stacks[RECYCLESTACKSIZE];
102 /* ANSI ASSUMPTION: this array is initialize to NULL values */
103 /* Assumption about client:
104 * It will never try to free any element of the stack, nor
105 * will it ever put the stack inside a struct value_t managed
106 * (created and therefore destroyed) by value_type.c.
107 * Nor will the client ever give the stack to someone else to
108 * deallocate later.
109 */
110 static struct stack_t *CreateStack(unsigned int cap)
111 {
112 struct stack_t *result;
113 if (cap < RECYCLESTACKSIZE && g_recycle_expreval_stacks[cap] !=NULL) {
114 result = g_recycle_expreval_stacks[cap];
115 /* move the NEXT recycled pointer into recycle array */
116 g_recycle_expreval_stacks[cap] = (struct stack_t *)result->size;
117 result->size =0; /* ptr and capacity valid from initial allocation */
118 return result;
119 } else {
120 return AllocStack(cap);
121 }
122 }
123
124 static void DestroyStack(struct stack_t *stack)
125 {
126 if (stack==NULL) return;
127 if (stack->capacity < RECYCLESTACKSIZE) {
128 /* the recycle list NEXT pointer has to be cast into the size slot */
129 stack->size =(unsigned long)(g_recycle_expreval_stacks[stack->capacity]);
130 /* push stack on LIFO recycle list */
131 g_recycle_expreval_stacks[stack->capacity] = stack;
132 return;
133 } else {
134 DeAllocStack(stack);
135 }
136 }
137
138 /* Clear and reinit expression stack recycler */
139 #define PRINTSTACKSTATS 0
140 void ClearRecycleStack(void) {
141 unsigned int i,cnt;
142 struct stack_t *stp; /* pointer to a recycled stack */
143 #if PRINTSTACKSTATS
144 PRINTF("Stack cap.\tRecycle\n");
145 #endif
146 for (i=0; i < RECYCLESTACKSIZE; i++) {
147 cnt=0;
148 while( (stp = g_recycle_expreval_stacks[i]) != NULL) {
149 g_recycle_expreval_stacks[i] = (struct stack_t *)stp->size;
150 DeAllocStack(stp);
151 cnt++;
152 }
153 #if PRINTSTACKSTATS
154 PRINTF("%d\t\t%d\n",i,cnt);
155 #endif
156 }
157 }
158
159 #ifndef NDEBUG
160 static
161 unsigned long StackSize(struct stack_t *stack)
162 {
163 assert(stack&&stack->ptr);
164 return stack->size;
165 }
166 #endif
167
168 static
169 struct value_t StackPopTop(struct stack_t *stack)
170 {
171 assert(stack&&stack->ptr&&stack->size);
172 return stack->ptr[--(stack->size)];
173 }
174
175 static
176 void StackPush(struct stack_t *stack, struct value_t value)
177 {
178 assert(stack&&stack->ptr&&(stack->size<stack->capacity));
179 stack->ptr[(stack->size)++] = value;
180 }
181
182 /*********************************************************************\
183 Expression Evaluation Routines.
184 \*********************************************************************/
185
186 static
187 unsigned int ExprStackDepth(CONST struct Expr *ex,
188 CONST struct Expr *stop)
189 {
190 register unsigned int maxdepth=0,depth=0;
191 while (ex!=stop){
192 AssertMemory(ex);
193 switch(ExprType(ex)){
194 case e_var:
195 case e_zero:
196 case e_int:
197 case e_satisfied:
198 case e_real:
199 case e_boolean:
200 case e_set:
201 case e_symbol:
202 case e_card:
203 case e_choice:
204 case e_sum:
205 case e_prod:
206 case e_union:
207 case e_inter:
208 if ((++depth)>maxdepth) maxdepth=depth;
209 break;
210 /* binary operators */
211 case e_plus:
212 case e_minus:
213 case e_times:
214 case e_divide:
215 case e_power:
216 case e_ipower:
217 case e_or:
218 case e_and:
219 case e_in:
220 case e_equal:
221 case e_notequal:
222 case e_less:
223 case e_greater:
224 case e_lesseq:
225 case e_greatereq:
226 case e_boolean_eq:
227 case e_boolean_neq:
228 depth--;
229 break;
230 case e_st:
231 Asc_Panic(2, NULL,
232 "Such that in atoms is unsupported for the time being.\n");
233 break;
234 /* no change*/
235 case e_func:
236 case e_uminus:
237 case e_not:
238 break;
239 case e_minimize:
240 case e_maximize:
241 Asc_Panic(2, NULL,
242 "Maximize and minimize aren't allowed in expressions.\n"
243 "They are only allowed in relations.\n");
244 break;
245 default:
246 Asc_Panic(2, NULL, "Unknown expression node type.\n");
247 break;
248 }
249 ex = NextExpr(ex);
250 }
251 return maxdepth;
252 }
253
254 static
255 CONST struct Expr *ContainsSuchThat(CONST struct Expr *expr,
256 CONST struct Expr *stop)
257 {
258 while (expr!=stop){
259 AssertMemory(expr);
260 if (ExprType(expr)==e_st) return expr;
261 expr = NextExpr(expr);
262 }
263 return 0;
264 }
265
266 static
267 unsigned SuchThatForm(CONST struct Expr *expr,
268 CONST struct Expr *stop,
269 CONST struct Expr **depth_one)
270 {
271 unsigned depth=0;
272 CONST struct Expr *previous=NULL;
273 *depth_one = NULL;
274 while (expr!=stop){
275 AssertMemory(expr);
276 switch(ExprType(expr)){
277 case e_var:
278 case e_zero:
279 case e_int:
280 case e_satisfied:
281 case e_real:
282 case e_boolean:
283 case e_set:
284 case e_symbol:
285 case e_card:
286 case e_choice:
287 case e_sum:
288 case e_prod:
289 case e_union:
290 case e_inter:
291 if ((++depth)==1) *depth_one = expr;
292 break;
293 /* binary operators */
294 case e_plus:
295 case e_minus:
296 case e_times:
297 case e_divide:
298 case e_power:
299 case e_ipower:
300 case e_or:
301 case e_and:
302 case e_in:
303 case e_equal:
304 case e_notequal:
305 case e_less:
306 case e_greater:
307 case e_lesseq:
308 case e_greatereq:
309 case e_boolean_eq:
310 case e_boolean_neq:
311 if ((--depth)==1) *depth_one = expr;
312 break;
313 case e_func:
314 case e_uminus:
315 case e_not:
316 if (depth==1) *depth_one = expr;
317 break;
318 case e_st:
319 if (previous==NULL) return 2; /* error */
320 if (NextExpr(expr)!=stop) return 2; /* error */
321 if (ExprType(*depth_one)==e_in) return 0; /* set definition */
322 if (ExprType(previous)==e_in) return 1; /* list of values */
323 return 2; /* error */
324 case e_minimize:
325 case e_maximize:
326 Asc_Panic(2, NULL,
327 "Maximize and minimize are not allowed in expression.\n"
328 "They are only allowed in relations.\n");
329 break;
330 default:
331 Asc_Panic(2, NULL, "Unknown expression node type.\n");
332 break;
333 }
334 previous = expr;
335 expr = NextExpr(expr);
336 }
337 return 2;
338 }
339
340 static
341 int GetNameAndSet(CONST struct Expr *ex, CONST struct Expr *stop,
342 symchar **name, struct value_t *value,
343 struct value_t (*EvaluateName) (/* ??? */))
344 {
345 /* NAME SET IN */
346 if (ExprType(ex)==e_var){
347 if ((*name = SimpleNameIdPtr(ExprName(ex)))!=NULL){
348 *value = EvaluateExpr(NextExpr(ex),stop,EvaluateName);
349 if (ValueKind(*value)==set_value) {
350 return 0;
351 }
352 if (ValueKind(*value)==error_value) {
353 return 1;
354 } else {
355 if (ValueKind(*value)==integer_value) {
356 FPRINTF(ASCERR,
357 "Asc-Error: Found integer constant where set expected: ");
358 WriteExprNode(ASCERR,NextExpr(ex));
359 FPRINTF(ASCERR,"\n");
360 }
361 if (ValueKind(*value)==symbol_value) {
362 FPRINTF(ASCERR,
363 "Asc-Error: Found symbol constant where set expected: ");
364 WriteExprNode(ASCERR,NextExpr(ex));
365 FPRINTF(ASCERR,"\n");
366 }
367 DestroyValue(value);
368 *value = CreateErrorValue(type_conflict);
369 return 1;
370 }
371 }
372 }
373 *value = CreateErrorValue(incorrect_such_that);
374 return 1;
375 }
376
377 static
378 int GetNameAndSetNamesNeeded(CONST struct Expr *ex,
379 CONST struct Expr *stop,
380 symchar **name)
381 {
382 /* NAME SET IN */
383 if (ExprType(ex)==e_var){
384 *name = SimpleNameIdPtr(ExprName(ex));
385 if (*name != NULL){
386 EvaluateNamesNeeded(NextExpr(ex),stop,GNN);
387 }
388 return 0;
389 }
390 return 1;
391 }
392
393 static
394 struct value_t EvaluateLeftIteration(CONST struct Expr *expr,
395 CONST struct Expr *stop,
396 CONST struct Expr *depth_one,
397 struct value_t (*EvaluateName)(/* ??? */))
398 {
399 CONST struct Expr *st_node,*rhs;
400 struct set_t *sptr;
401 symchar *tmp_name; /* name of temporary variable */
402 struct value_t iteration_set,tmp_value,l_value,rhs_value;
403 unsigned long c,len;
404 IVAL(iteration_set);
405 IVAL(tmp_value);
406 IVAL(l_value);
407 IVAL(rhs_value);
408 if (GetNameAndSet(expr,depth_one,&tmp_name,&iteration_set,EvaluateName)) {
409 return iteration_set;
410 }
411 sptr = SetValue(iteration_set);
412 rhs = NextExpr(depth_one);
413 st_node = ContainsSuchThat(rhs,stop);
414 switch(SetKind(sptr)){
415 case empty_set:
416 DestroyValue(&iteration_set);
417 return CreateVacantListValue();
418 case integer_set:
419 case string_set:
420 if (TempExists(tmp_name)){
421 FPRINTF(ASCERR,"Reused temporary variable %s.\n",SCP(tmp_name));
422 DestroyValue(&iteration_set);
423 return CreateErrorValue(temporary_variable_reused);
424 }
425 l_value = CreateEmptyListValue();
426 AddTemp(tmp_name);
427 len = Cardinality(sptr);
428 for(c=1;c<=len;c++){
429 if (SetKind(sptr)==string_set) {
430 tmp_value = CreateSymbolValue(FetchStrMember(sptr,c),1);
431 } else {
432 tmp_value = CreateIntegerValue(FetchIntMember(sptr,c),1);
433 }
434 SetTemp(tmp_name,tmp_value);
435 rhs_value =EvaluateExpr(rhs,st_node,EvaluateName);
436 if (ValueKind(rhs_value)!=boolean_value){
437 DestroyValue(&tmp_value);
438 RemoveTemp(tmp_name);
439 DestroyValue(&iteration_set);
440 DestroyValue(&l_value);
441 if (ValueKind(rhs_value)==error_value) {
442 return rhs_value;
443 } else {
444 DestroyValue(&rhs_value);
445 return CreateErrorValue(incorrect_such_that);
446 }
447 }
448 if (BooleanValue(rhs_value)) {
449 AppendToListValue(l_value,tmp_value);
450 }
451 DestroyValue(&tmp_value);
452 DestroyValue(&rhs_value);
453 }
454 RemoveTemp(tmp_name);
455 DestroyValue(&iteration_set);
456 return l_value;
457 }
458 /*NOTREACHED*/
459 FPRINTF(ASCERR,"EvaluateLeftIteration returning erroneous value\n");
460 return tmp_value;
461 }
462
463 static
464 void EvaluateLeftIterationNamesNeeded(CONST struct Expr *expr,
465 CONST struct Expr *stop,
466 CONST struct Expr *depth_one)
467 {
468 CONST struct Expr *st_node,*rhs;
469 symchar *tmp_name; /* name of temporary variable */
470 if (GetNameAndSetNamesNeeded(expr,depth_one,&tmp_name)) {
471 return;
472 }
473 rhs = NextExpr(depth_one);
474 st_node = ContainsSuchThat(rhs,stop);
475 if (tmp_name !=NULL && TempExists(tmp_name)){
476 FPRINTF(ASCERR,"Reused temporary variable %s.\n",SCP(tmp_name));
477 }
478 AddTemp(tmp_name);
479 GNN = EvaluateNamesNeeded(rhs,st_node,GNN);
480 RemoveTemp(tmp_name);
481 return;
482 }
483
484 static
485 CONST struct Expr *NodeBeforeSuchThat(CONST struct Expr *ex)
486 {
487 while(ExprType(NextExpr(ex))!=e_st) {
488 ex = NextExpr(ex);
489 }
490 return ex;
491 }
492
493 static
494 struct value_t EvaluateRightIteration(CONST struct Expr *expr,
495 CONST struct Expr *stop,
496 CONST struct Expr *depth_one,
497 struct value_t (*EvaluateName)(/*???*/))
498 {
499 symchar *tmp_name;
500 CONST struct Expr *node;
501 struct value_t iteration_set,l_value,tmp_value,lhs_value;
502 struct set_t *sptr;
503 unsigned long c,len;
504
505 (void)stop; /* stop gcc whine about unused parameter */
506
507 IVAL(iteration_set);
508 IVAL(tmp_value);
509 IVAL(l_value);
510 IVAL(lhs_value);
511 node = NodeBeforeSuchThat(depth_one);
512 if (GetNameAndSet(NextExpr(depth_one),node,
513 &tmp_name,&iteration_set,EvaluateName))
514 return iteration_set;
515 node = NextExpr(depth_one);
516 sptr = SetValue(iteration_set);
517 switch(SetKind(sptr)){
518 case empty_set:
519 DestroyValue(&iteration_set);
520 return CreateVacantListValue();
521 case integer_set:
522 case string_set:
523 if (TempExists(tmp_name)){
524 FPRINTF(ASCERR,"Reused temporary variable %s.\n",SCP(tmp_name));
525 DestroyValue(&iteration_set);
526 return CreateErrorValue(temporary_variable_reused);
527 }
528 l_value = CreateEmptyListValue();
529 AddTemp(tmp_name);
530 len = Cardinality(sptr);
531 for(c=1;c<=len;c++){
532 if (SetKind(sptr)==string_set) {
533 tmp_value = CreateSymbolValue(FetchStrMember(sptr,c),1);
534 } else {
535 tmp_value = CreateIntegerValue(FetchIntMember(sptr,c),1);
536 }
537 SetTemp(tmp_name,tmp_value);
538 lhs_value=EvaluateExpr(expr,node,EvaluateName);
539 if (ValueKind(lhs_value)==error_value){
540 DestroyValue(&tmp_value);
541 RemoveTemp(tmp_name);
542 DestroyValue(&iteration_set);
543 DestroyValue(&l_value);
544 return lhs_value;
545 }
546 AppendToListValue(l_value,lhs_value);
547 DestroyValue(&tmp_value);
548 }
549 RemoveTemp(tmp_name);
550 DestroyValue(&iteration_set);
551 return l_value;
552 }
553 /*NOTREACHED*/
554 FPRINTF(ASCERR,"EvaluateRightIteration returning erroneous value\n");
555 return tmp_value;
556 }
557
558 static
559 void EvaluateRightIterationNamesNeeded(CONST struct Expr *expr,
560 CONST struct Expr *stop,
561 CONST struct Expr *depth_one)
562 {
563 symchar *tmp_name;
564 CONST struct Expr *node;
565
566 (void)stop; /* stop gcc whine about unused parameter */
567
568 node = NodeBeforeSuchThat(depth_one);
569 if (GetNameAndSetNamesNeeded(NextExpr(depth_one),node,&tmp_name)) {
570 return;
571 }
572 node = NextExpr(depth_one);
573 if (tmp_name !=NULL && TempExists(tmp_name)){
574 FPRINTF(ASCERR,"Reused temporary variable %s.\n",SCP(tmp_name));
575 return;
576 }
577 AddTemp(tmp_name);
578 GNN = EvaluateNamesNeeded(expr,node,GNN);
579 RemoveTemp(tmp_name);
580 return;
581 }
582
583 static
584 struct value_t EvaluateSuchThat(CONST struct Expr *expr,
585 CONST struct Expr *stop,
586 struct value_t (*EvaluateName) (/* ??? */))
587 {
588 CONST struct Expr *depth_one;
589 switch(SuchThatForm(expr,stop,&depth_one)){
590 case 0:
591 return EvaluateLeftIteration(expr,stop,depth_one,EvaluateName);
592 case 1:
593 return EvaluateRightIteration(expr,stop,depth_one,EvaluateName);
594 default:
595 return CreateErrorValue(incorrect_such_that);
596 }
597 }
598
599 static
600 void EvaluateSuchThatNamesNeeded(CONST struct Expr *expr,
601 CONST struct Expr *stop)
602
603 {
604 CONST struct Expr *depth_one;
605 switch(SuchThatForm(expr,stop,&depth_one)){
606 case 0:
607 EvaluateLeftIterationNamesNeeded(expr,stop,depth_one);
608 return;
609 case 1:
610 EvaluateRightIterationNamesNeeded(expr,stop,depth_one);
611 return;
612 default:
613 break;
614 }
615 }
616
617 struct value_t EvaluateExpr(CONST struct Expr *expr, CONST struct Expr *stop,
618 struct value_t (*EvaluateName) (/* ? */))
619 {
620 struct value_t top,next;
621 symchar *cptr;
622 register struct stack_t *stack;
623 IVAL(top);
624 IVAL(next);
625 if (ContainsSuchThat(expr,stop)!=NULL) {
626 return EvaluateSuchThat(expr,stop,EvaluateName);
627 }
628 stack = CreateStack(ExprStackDepth(expr,stop));
629 while(expr!=stop){
630 AssertMemory(expr);
631 switch(ExprType(expr)){
632 case e_var: /* variable */
633 cptr = SimpleNameIdPtr(ExprName(expr));
634 if ((cptr != NULL)&&TempExists(cptr)) {
635 top = TempValue(cptr);
636 } else {
637 top = (*EvaluateName)(ExprName(expr));
638 }
639 StackPush(stack,top);
640 break;
641 case e_func: /* function evaluation */
642 top = ApplyFunction(StackPopTop(stack),ExprFunc(expr));
643 StackPush(stack,top);
644 break;
645 case e_satisfied: /* satisfied evaluation */
646 top = InstanceEvaluateSatisfiedName(SatisfiedExprName(expr),
647 SatisfiedExprRValue(expr));
648 StackPush(stack,top);
649 break;
650 case e_int: /* integer constant */
651 top = CreateIntegerValue(ExprIValue(expr),1);
652 StackPush(stack,top);
653 break;
654 case e_zero: /* ambiguous 0 */
655 top = CreateRealValue(0.0,WildDimension(),1);
656 StackPush(stack,top);
657 break;
658 case e_real: /* real constant */
659 top = CreateRealValue(ExprRValue(expr),ExprRDimensions(expr),1);
660 StackPush(stack,top);
661 break;
662 case e_boolean: /* boolean constant */
663 top = CreateBooleanValue(ExprBValue(expr),1);
664 StackPush(stack,top);
665 break;
666 case e_set: /* set */
667 top = EvaluateSet(ExprSValue(expr),EvaluateName);
668 StackPush(stack,CreateSetFromList(top));
669 DestroyValue(&top);
670 break;
671 case e_symbol: /* symbol constant */
672 top = CreateSymbolValue(ExprSymValue(expr),1);
673 StackPush(stack,top);
674 break;
675 case e_plus: /* binary plus operator */
676 top = StackPopTop(stack);
677 next = StackPopTop(stack);
678 StackPush(stack,AddValues(next,top));
679 DestroyValue(&top);
680 DestroyValue(&next);
681 break;
682 case e_minus: /* binary minus operator */
683 top = StackPopTop(stack);
684 next = StackPopTop(stack);
685 StackPush(stack,SubtractValues(next,top));
686 DestroyValue(&top);
687 DestroyValue(&next);
688 break;
689 case e_times: /* binary multiplication operator */
690 top = StackPopTop(stack);
691 next = StackPopTop(stack);
692 StackPush(stack,MultiplyValues(next,top));
693 DestroyValue(&top);
694 DestroyValue(&next);
695 break;
696 case e_divide: /* binary division operator */
697 top = StackPopTop(stack);
698 next = StackPopTop(stack);
699 StackPush(stack,DivideValues(next,top));
700 DestroyValue(&top);
701 DestroyValue(&next);
702 break;
703 case e_power: /* binary exponentiation operator */
704 case e_ipower: /* binary exponentiation operator */
705 top = StackPopTop(stack);
706 next = StackPopTop(stack);
707 StackPush(stack,PowerValues(next,top));
708 DestroyValue(&top);
709 DestroyValue(&next);
710 break;
711 case e_card: /* cardinality operator */
712 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
713 next = CreateSetFromList(top);
714 StackPush(stack,CardValues(next));
715 DestroyValue(&top);
716 DestroyValue(&next);
717 break;
718 case e_choice: /* choice operator */
719 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
720 next = CreateSetFromList(top);
721 StackPush(stack,ChoiceValues(next));
722 DestroyValue(&top);
723 DestroyValue(&next);
724 break;
725 case e_sum: /* summation operator */
726 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
727 StackPush(stack,SumValues(top));
728 DestroyValue(&top);
729 break;
730 case e_prod: /* product operator */
731 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
732 StackPush(stack,ProdValues(top));
733 DestroyValue(&top);
734 break;
735 case e_union: /* union operator */
736 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
737 StackPush(stack,UnionValues(top));
738 DestroyValue(&top);
739 break;
740 case e_inter: /* intersection operator */
741 top = EvaluateSet(ExprBuiltinSet(expr),EvaluateName);
742 StackPush(stack,IntersectionValues(top));
743 DestroyValue(&top);
744 break;
745 case e_or: /* binary logical OR operator */
746 top = StackPopTop(stack);
747 next = StackPopTop(stack);
748 StackPush(stack,OrValues(next,top));
749 DestroyValue(&top);
750 DestroyValue(&next);
751 break;
752 case e_and: /* binary logical AND operator */
753 top = StackPopTop(stack);
754 next = StackPopTop(stack);
755 StackPush(stack,AndValues(next,top));
756 DestroyValue(&top);
757 DestroyValue(&next);
758 break;
759 case e_in: /* set membership test */
760 top = StackPopTop(stack);
761 next = StackPopTop(stack);
762 StackPush(stack,InValues(next,top));
763 DestroyValue(&top);
764 DestroyValue(&next);
765 break;
766 case e_equal: /* equality test */
767 case e_boolean_eq: /* these two ought to be separated */
768 /* = should bind more tightly than == */
769 top = StackPopTop(stack);
770 next = StackPopTop(stack);
771 StackPush(stack,EqualValues(next,top));
772 DestroyValue(&top);
773 DestroyValue(&next);
774 break;
775 case e_notequal: /* non-equality test */
776 case e_boolean_neq: /* these two ought to be separated */
777 /* <> should bind more tightly than != */
778 top = StackPopTop(stack);
779 next = StackPopTop(stack);
780 StackPush(stack,NotEqualValues(next,top));
781 DestroyValue(&top);
782 DestroyValue(&next);
783 break;
784 case e_less: /* less than test */
785 top = StackPopTop(stack);
786 next = StackPopTop(stack);
787 StackPush(stack,LessValues(next,top));
788 DestroyValue(&top);
789 DestroyValue(&next);
790 break;
791 case e_greater: /* greater than test */
792 top = StackPopTop(stack);
793 next = StackPopTop(stack);
794 StackPush(stack,GreaterValues(next,top));
795 DestroyValue(&top);
796 DestroyValue(&next);
797 break;
798 case e_lesseq: /* less then or equal test */
799 top = StackPopTop(stack);
800 next = StackPopTop(stack);
801 StackPush(stack,LessEqValues(next,top));
802 DestroyValue(&top);
803 DestroyValue(&next);
804 break;
805 case e_greatereq: /* greater than or equal test */
806 top = StackPopTop(stack);
807 next = StackPopTop(stack);
808 StackPush(stack,GreaterEqValues(next,top));
809 DestroyValue(&top);
810 DestroyValue(&next);
811 break;
812 case e_uminus: /* unary minus operator */
813 top = StackPopTop(stack);
814 StackPush(stack,NegateValue(top));
815 DestroyValue(&top);
816 break;
817 case e_not: /* unary logical NOT operator */
818 top = StackPopTop(stack);
819 StackPush(stack,NotValue(top));
820 DestroyValue(&top);
821 break;
822 case e_st: /* such that */
823 Asc_Panic(2, NULL, "Something is royally wrong is EvaluateExpr.\n");
824 break;
825 case e_minimize:
826 case e_maximize:
827 Asc_Panic(2, NULL,
828 "Maximize and minimize are not allowed in expression.\n"
829 "They are only allowed in relations.\n");
830 break;
831 default:
832 Asc_Panic(2, NULL, "Unknown expression node in EvaluateExpr.\n");
833 break;
834 }
835 expr = NextExpr(expr);
836 }
837 assert(StackSize(stack)==1);
838 top = StackPopTop(stack);
839 DestroyStack(stack);
840 return top;
841 }
842
843 struct gl_list_t *EvaluateNamesNeeded(CONST struct Expr *expr,
844 CONST struct Expr *stop,
845 struct gl_list_t *nlist)
846 {
847 symchar *cptr;
848 CONST struct Name *n;
849
850 if (nlist ==NULL) {
851 nlist= gl_create(3L);
852 }
853 assert(nlist!=NULL);
854 GNN = nlist; /* always done, so we don't need to set it back NULL after */
855
856 if (ContainsSuchThat(expr,stop)!=NULL) {
857 EvaluateSuchThatNamesNeeded(expr,stop);
858 return GNN;
859 }
860 while(expr!=stop){
861 AssertMemory(expr);
862 switch(ExprType(expr)){
863 case e_var: /* variable */
864 cptr = SimpleNameIdPtr(ExprName(expr));
865 if ( cptr == NULL || TempExists(cptr)==0 ) {
866 /* append if name not already seen in list */
867 if (gl_search(nlist,(VOIDPTR)ExprName(expr),
868 (CmpFunc)CompareNames) == 0L)
869 {
870 gl_append_ptr(nlist,(VOIDPTR)ExprName(expr));
871 }
872 }
873 n = ExprName(expr);
874 n = NextName(n);
875 while (n != NULL) {
876 if (NameId(n) == 0) {
877 GNN = EvaluateSetNamesNeeded(NameSetPtr(n),GNN);
878 }
879 n = NextName(n);
880 }
881 break;
882 case e_func: /* function evaluation */
883 case e_int: /* integer constant */
884 case e_zero: /* ambiguous 0 */
885 case e_real: /* real constant */
886 case e_boolean: /* boolean constant */
887 case e_satisfied: /* satisified expression */
888 break;
889 case e_set: /* set */
890 GNN = EvaluateSetNamesNeeded(ExprSValue(expr),GNN);
891 break;
892 case e_symbol: /* symbol constant */
893 case e_plus: /* binary plus operator */
894 case e_minus: /* binary minus operator */
895 case e_times: /* binary multiplication operator */
896 case e_divide: /* binary division operator */
897 case e_power: /* binary exponentiation operator */
898 case e_ipower: /* binary exponentiation operator */
899 break;
900 case e_card: /* cardinality operator */
901 case e_choice: /* choice operator */
902 case e_sum: /* summation operator */
903 case e_prod: /* product operator */
904 case e_union: /* union operator */
905 case e_inter: /* intersection operator */
906 GNN = EvaluateSetNamesNeeded(ExprBuiltinSet(expr),GNN);
907 break;
908 case e_or: /* binary logical OR operator */
909 case e_and: /* binary logical AND operator */
910 case e_in: /* set membership test */
911 case e_equal: /* equality test */
912 case e_bol_token:
913 case e_boolean_eq:
914 case e_boolean_neq:
915 case e_notequal: /* non-equality test */
916 case e_less: /* less than test */
917 case e_greater: /* greater than test */
918 case e_lesseq: /* less then or equal test */
919 case e_greatereq: /* greater than or equal test */
920 case e_uminus: /* unary minus operator */
921 case e_not: /* unary logical NOT operator */
922 break;
923 case e_st: /* such that */
924 Asc_Panic(2, "EvaluateNamesNeeded",
925 "Something is royally wrong is EvaluateNamesNeeded.\n");
926 break;
927 case e_minimize:
928 case e_maximize:
929 break;
930 default:
931 Asc_Panic(2, NULL, "Unknown expression node in EvaluateNamesNeeded.\n");
932 break;
933 }
934 expr = NextExpr(expr);
935 }
936 return GNN;
937 }
938
939 struct gl_list_t *EvaluateNamesNeededShallow(CONST struct Expr *expr,
940 CONST struct Expr *stop,
941 struct gl_list_t *nlist)
942 {
943 symchar *cptr;
944
945 if (nlist ==NULL) {
946 nlist= gl_create(3L);
947 }
948 assert(nlist!=NULL);
949 GNN = nlist; /* always done, so we don't need to set it back NULL after */
950
951 if (ContainsSuchThat(expr,stop)!=NULL) {
952 EvaluateSuchThatNamesNeeded(expr,stop);
953 return GNN;
954 }
955 while(expr!=stop){
956 AssertMemory(expr);
957 switch(ExprType(expr)){
958 case e_var: /* variable */
959 cptr = SimpleNameIdPtr(ExprName(expr));
960 if ( cptr == NULL || TempExists(cptr)==0 ) {
961 /* append if name not already seen in list */
962 if (gl_search(nlist,(VOIDPTR)ExprName(expr),
963 (CmpFunc)CompareNames) == 0L)
964 {
965 gl_append_ptr(nlist,(VOIDPTR)ExprName(expr));
966 }
967 }
968 break;
969 case e_func: /* function evaluation */
970 case e_int: /* integer constant */
971 case e_zero: /* ambiguous 0 */
972 case e_real: /* real constant */
973 case e_boolean: /* boolean constant */
974 case e_satisfied: /* satisified expression */
975 break;
976 case e_set: /* set */
977 GNN = EvaluateSetNamesNeededShallow(ExprSValue(expr),GNN);
978 break;
979 case e_symbol: /* symbol constant */
980 case e_plus: /* binary plus operator */
981 case e_minus: /* binary minus operator */
982 case e_times: /* binary multiplication operator */
983 case e_divide: /* binary division operator */
984 case e_power: /* binary exponentiation operator */
985 case e_ipower: /* binary exponentiation operator */
986 break;
987 case e_card: /* cardinality operator */
988 case e_choice: /* choice operator */
989 case e_sum: /* summation operator */
990 case e_prod: /* product operator */
991 case e_union: /* union operator */
992 case e_inter: /* intersection operator */
993 GNN = EvaluateSetNamesNeededShallow(ExprBuiltinSet(expr),GNN);
994 break;
995 case e_or: /* binary logical OR operator */
996 case e_and: /* binary logical AND operator */
997 case e_in: /* set membership test */
998 case e_equal: /* equality test */
999 case e_bol_token:
1000 case e_boolean_eq:
1001 case e_boolean_neq:
1002 case e_notequal: /* non-equality test */
1003 case e_less: /* less than test */
1004 case e_greater: /* greater than test */
1005 case e_lesseq: /* less then or equal test */
1006 case e_greatereq: /* greater than or equal test */
1007 case e_uminus: /* unary minus operator */
1008 case e_not: /* unary logical NOT operator */
1009 break;
1010 case e_st: /* such that */
1011 Asc_Panic(2, "EvaluateNamesNeededShallow",
1012 "Something is wrong in EvaluateNamesNeededShallow.\n");
1013 break;
1014 case e_minimize:
1015 case e_maximize:
1016 break;
1017 default:
1018 Asc_Panic(2, "EvaluateNamesNeededShallow",
1019 "Unknown expression in EvaluateNamesNeededShallow.\n");
1020 break;
1021 }
1022 expr = NextExpr(expr);
1023 }
1024 return GNN;
1025 }
1026
1027 /* in this function we should do a bunch of logic checking before
1028 * calling the CreateEmptyList; if we can he accounts for most
1029 * of our memory activity
1030 */
1031 struct value_t EvaluateSet(CONST struct Set *sptr,
1032 struct value_t (*EvaluateName) (/* ??? */))
1033 {
1034 struct value_t result,lower,upper;
1035 long l,u,c;
1036 int previous_state;
1037 previous_state = EvaluatingSets; /* save the state as called recursively */
1038 EvaluatingSets = 1;
1039 result = CreateEmptyListValue();
1040 while (sptr!=NULL){
1041 AssertMemory(sptr);
1042 if (SetType(sptr)){ /* range */
1043 lower = EvaluateExpr(GetLowerExpr(sptr),NULL,EvaluateName);
1044 if (ValueKind(lower)==error_value){
1045 DestroyValue(&result);
1046 EvaluatingSets = previous_state;
1047 return lower;
1048 }
1049 upper = EvaluateExpr(GetUpperExpr(sptr),NULL,EvaluateName);
1050 if (ValueKind(upper)==error_value){
1051 DestroyValue(&lower);
1052 DestroyValue(&result);
1053 EvaluatingSets = previous_state;
1054 return upper;
1055 }
1056 if((ValueKind(lower)!=integer_value)||(ValueKind(upper)!=integer_value)){
1057 DestroyValue(&lower);
1058 DestroyValue(&upper);
1059 DestroyValue(&result);
1060 EvaluatingSets = previous_state;
1061 return CreateErrorValue(type_conflict);
1062 }
1063 l = IntegerValue(lower);
1064 u = IntegerValue(upper);
1065 DestroyValue(&lower);
1066 DestroyValue(&upper);
1067 for(c=l;c<=u;c++) {
1068 AppendToListValue(result,CreateIntegerValue(c,1));
1069 }
1070 } else { /* singleton */
1071 lower = EvaluateExpr(GetSingleExpr(sptr),NULL,EvaluateName);
1072 if (ValueKind(lower)==error_value){
1073 DestroyValue(&result);
1074 EvaluatingSets = previous_state;
1075 return lower;
1076 }
1077 AppendToListValue(result,lower);
1078 }
1079 sptr = NextSet(sptr);
1080 }
1081 EvaluatingSets = previous_state;
1082 return result;
1083 }
1084
1085 /* in this function we should do a bunch of logic checking before
1086 * calling the CreateEmptyList; if we can he accounts for most
1087 * of our memory activity.
1088 */
1089 struct gl_list_t *EvaluateSetNamesNeeded(CONST struct Set *sptr,
1090 struct gl_list_t *nlist)
1091 {
1092 if (nlist ==NULL) {
1093 nlist= gl_create(3L);
1094 }
1095 assert(nlist!=NULL);
1096 GNN = nlist; /* always done, so we don't need to set it back NULL after */
1097
1098 while (sptr!=NULL){
1099 AssertMemory(sptr);
1100 if (SetType(sptr)){ /* range */
1101 GNN = EvaluateNamesNeeded(GetLowerExpr(sptr),NULL,GNN);
1102 GNN = EvaluateNamesNeeded(GetUpperExpr(sptr),NULL,GNN);
1103 } else { /* singleton */
1104 GNN = EvaluateNamesNeeded(GetSingleExpr(sptr),NULL,GNN);
1105 }
1106 sptr = NextSet(sptr);
1107 }
1108 return GNN;
1109 }
1110
1111 /* in this function we should do a bunch of logic checking before
1112 * calling the CreateEmptyList; if we can he accounts for most
1113 * of our memory activity.
1114 */
1115 struct gl_list_t *EvaluateSetNamesNeededShallow(CONST struct Set *sptr,
1116 struct gl_list_t *nlist)
1117 {
1118 if (nlist ==NULL) {
1119 nlist= gl_create(3L);
1120 }
1121 assert(nlist!=NULL);
1122 GNN = nlist; /* always done, so we don't need to set it back NULL after */
1123
1124 while (sptr!=NULL){
1125 AssertMemory(sptr);
1126 if (SetType(sptr)){ /* range */
1127 GNN = EvaluateNamesNeededShallow(GetLowerExpr(sptr),NULL,GNN);
1128 GNN = EvaluateNamesNeededShallow(GetUpperExpr(sptr),NULL,GNN);
1129 } else { /* singleton */
1130 GNN = EvaluateNamesNeededShallow(GetSingleExpr(sptr),NULL,GNN);
1131 }
1132 sptr = NextSet(sptr);
1133 }
1134 return GNN;
1135 }

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