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

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