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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 101 - (show annotations) (download) (as text)
Sat Dec 10 04:22:07 2005 UTC (15 years, 4 months ago) by jds
File MIME type: text/x-csrc
File size: 26347 byte(s)
A little more progress killing compiler warnings.
1 /*
2 * Ascend Instance Refinement Functions
3 * by Tom Epperly & Ben Allan1
4 * 9/3/89
5 * Version: $Revision: 1.10 $
6 * Version control file: $RCSfile: refineinst.c,v $
7 * Date last modified: $Date: 1998/02/05 16:37:32 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1996 Ben Allan
13 * based on instance.c
14 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
15 *
16 * The Ascend Language Interpreter is free software; you can redistribute
17 * it and/or modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of the
19 * License, or (at your option) any later version.
20 *
21 * The Ascend Language Interpreter is distributed in hope that it will be
22 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with the program; if not, write to the Free Software Foundation,
28 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
29 * COPYING.
30 *
31 */
32 #include <stdarg.h>
33 #include "utilities/ascConfig.h"
34 #include "utilities/ascPanic.h"
35 #include "utilities/ascMalloc.h"
36 #include "general/pool.h"
37 #include "general/list.h"
38 #include "general/dstring.h"
39 #include "compiler/compiler.h"
40 #include "compiler/bit.h"
41 #include "compiler/symtab.h"
42 #include "compiler/fractions.h"
43 #include "compiler/dimen.h"
44 #include "compiler/functype.h"
45 #include "compiler/types.h"
46 #include "compiler/instance_enum.h"
47 #include "compiler/stattypes.h"
48 #include "compiler/slist.h"
49 #include "compiler/instance_name.h"
50 #include "compiler/instance_io.h"
51 #include "compiler/check.h"
52 #include "compiler/dump.h"
53 #include "compiler/child.h"
54 #include "compiler/type_desc.h"
55 #include "compiler/prototype.h"
56 #include "compiler/pending.h"
57 #include "compiler/find.h"
58 #include "compiler/relation_type.h"
59 #include "compiler/relation.h"
60 #include "compiler/logical_relation.h"
61 #include "compiler/logrelation.h"
62 #include "compiler/relation_util.h"
63 #include "compiler/logrel_util.h"
64 #include "compiler/rel_common.h"
65 #include "compiler/case.h"
66 #include "compiler/when_util.h"
67 #include "compiler/universal.h"
68 #include "compiler/setinstval.h"
69 #include "compiler/instance_types.h"
70 /* new */
71 #include "compiler/atomsize.h"
72 #include "compiler/atomvalue.h"
73 #include "compiler/cmpfunc.h"
74 #include "compiler/copyinst.h"
75 #include "compiler/createinst.h"
76 #include "compiler/destroyinst.h"
77 #include "compiler/extinst.h"
78 #include "compiler/instmacro.h"
79 #include "compiler/instquery.h"
80 #include "compiler/linkinst.h"
81 #include "compiler/mergeinst.h"
82 #include "compiler/parentchild.h"
83 #include "compiler/instantiate.h"
84 #include "compiler/refineinst.h"
85
86 #ifndef lint
87 static CONST char RefineInstModuleID[] = "$Id: refineinst.c,v 1.10 1998/02/05 16:37:32 ballan Exp $";
88 #endif
89
90
91 /* checks children, and does some value copying in the process */
92 static void CheckChild(struct Instance *old, struct Instance *new)
93 {
94 register CONST dim_type *dimp;
95 assert(old->t==new->t);
96 switch(old->t){
97 case REAL_INST:
98 dimp = CheckDimensionsMatch(R_INST(old)->dimen,R_INST(new)->dimen);
99 if (dimp==NULL){
100 FPRINTF(ASCERR,"Dimensional mismatch in CheckChild.\n");
101 R_INST(new)->dimen = R_INST(old)->dimen;
102 }
103 else
104 R_INST(new)->dimen = dimp;
105 if (R_INST(old)->assigned > R_INST(new)->assigned){
106 R_INST(new)->assigned = R_INST(old)->assigned;
107 R_INST(new)->depth = R_INST(old)->depth;
108 R_INST(new)->value = R_INST(old)->value;
109 }
110 break;
111 case BOOLEAN_INST:
112 if (B_INST(old)->assigned > B_INST(new)->assigned){
113 B_INST(new)->assigned = B_INST(old)->assigned;
114 B_INST(new)->depth = B_INST(old)->depth;
115 B_INST(new)->value = B_INST(old)->value;
116 }
117 break;
118 case INTEGER_INST:
119 if ((I_INST(old)->assigned)&&!(I_INST(new)->assigned)){
120 I_INST(new)->assigned = I_INST(old)->assigned;
121 I_INST(new)->value = I_INST(old)->value;
122 }
123 break;
124 case SET_INST:
125 #ifndef NDEBUG
126 if ((S_INST(old)->list)&&(S_INST(new)->list))
127 assert(SetsEqual(S_INST(old)->list,S_INST(new)->list));
128 #endif
129 if ((S_INST(old)->list!=NULL)&&(S_INST(new)->list==NULL)){
130 S_INST(new)->list = S_INST(old)->list;
131 S_INST(old)->list = NULL;
132 }
133 break;
134 case SYMBOL_INST:
135 #ifndef NDEBUG
136 if ((SYM_INST(new)->value!=NULL)&&(SYM_INST(new)->value!=NULL)) {
137 assert(SYM_INST(new)->value == SYM_INST(old)->value);
138 }
139 #endif
140 if ((SYM_INST(old)->value!=NULL)&&(SYM_INST(new)->value==NULL)) {
141 SYM_INST(new)->value = SYM_INST(old)->value;
142 }
143 break;
144 default:
145 Asc_Panic(2, NULL, "Incorrect type passed to CheckChild.\n");/*NOTREACHED*/
146 }
147 }
148
149 static
150 void CheckAtomValuesOne(register struct Instance **old,
151 register struct Instance **new,
152 register unsigned long int num)
153 {
154 while(num--)
155 CheckChild(*(old++),*(new++));
156 }
157
158 static
159 void CheckAtomValuesTwo(struct Instance *old, struct Instance *new)
160 {
161 register unsigned long c,num_children,pos;
162 struct InstanceName name;
163 num_children = NumberChildren(old);
164 for(c=1;c<=num_children;c++){
165 name = ChildName(old,c);
166 pos = ChildSearch(new,&name);
167 CheckChild(InstanceChild(old,c),InstanceChild(new,pos));
168 }
169 }
170
171
172 /* As constants never change size, this always returns the given i
173 unless it becomes universal and is replaced by already existing.
174 But note, the IRT universal with already existing universal inst case
175 never reaches here because it == ATS and is trapped in RefineInstance.
176 We do not handle that case for this reason. */
177 static struct Instance *RefineRealConstant(struct RealConstantInstance *i,
178 struct TypeDescription *type)
179 {
180 register CONST dim_type *dimp;
181 unsigned what=0;
182 /* bit game: bit 0 = update val,1 = update dim, bits 8,16= err in val/dim */
183
184 assert(MoreRefined(type,i->desc)==type); /* refinement possible? */
185 AssertMemory(i);
186 if (i->desc==type) return INST(i); /* if same type already, no work */
187 if (ShortCutMakeUniversalInstance(type)) {
188 /* NOT REACHED. see RefineRealAtom for expl. */
189 FPRINTF(ASCERR,"Program logic error in RefineRealConstant.\n");
190 FPRINTF(ASCERR,"Please report this message to %s.\n",ASC_BIG_BUGMAIL);
191 return INST(i);
192 }
193 /* Work: new type is more refined, at least in the library */
194 /* check for value and dimensions compatibility */
195 if (!CIASS(i)) {
196 if (ConstantDefaulted(type) ) {
197 what |= 1;
198 } /* else not assigned and not defaulted is fine. just leave value as is */
199 } else {
200 if ( (ConstantDefaulted(type) && i->value != GetConstantDefReal(type))
201 || !(ConstantDefaulted(type)) ) {
202 what |= 16;
203 /* we're hosed, type, value incompatible.possibly ahead of type. */
204 } /* else shut up and do not assign */
205 }
206
207 /* check dimensions */
208 dimp = GetConstantDimens(type);
209 if ( !(IsWild(dimp)) ) { /* do we get type's dims? */
210 if (IsWild(i->dimen)) { /* we do */
211 what |=2;
212 } else {
213 if( CheckDimensionsMatch(dimp,i->dimen)==NULL) {
214 what |= 8; /* hosed, dims mismatch */
215 } /* else dims already where they belong, shutup. */
216 }
217 } else { /* type is wild */
218 if (!IsWild(i->dimen)) what |= 8;
219 /* the instance can't be ahead of wild. funny implicit type case. */
220 }
221 if (what & 24) { /* something messed up */
222 if (what & 16) {
223 FPRINTF(ASCERR,"Value conflict in RefineRealConstant.\n");
224 }
225 if (what & 8) {
226 FPRINTF(ASCERR,"Dimensional conflict in RefineRealConstant.\n");
227 }
228 FPRINTF(ASCERR,"Unable to refine instance.\n");
229 } else { /* ok, fix it up */
230 if (what & 1) {
231 SetRealAtomValue(INST(i),GetConstantDefReal(type),0);
232 }
233 if (what & 2) {
234 SetRealAtomDims(INST(i),dimp);
235 }
236 if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
237 /* don't have to check universal table cause that was already up top */
238 AddUniversalInstance(GetUniversalTable(),type,INST(i));
239 }
240 /* else don't need to change universal table, cause we didn't move */
241 /* no move, so no parent update either */
242 i->desc = type; /* finally somebody make the refinement */
243 }
244 return INST(i); /* always returns i */
245 }
246
247 /*
248 * When the type of i is < type given, i will _always_
249 * end up being blown away, either by merging with a UNIVERSAL
250 * instance or by the copy to the new type. This needs to be
251 * rewritten so that atoms with the same size (number children)
252 * are always recycled rather than malloc/free'd.
253 */
254 static struct Instance *RefineRealAtom(struct RealAtomInstance *i,
255 struct TypeDescription *type)
256 {
257 struct RealAtomInstance *new;
258 register struct gl_list_t *tmp;
259 register CONST dim_type *dimp;
260 assert(MoreRefined(type,i->desc)==type);
261 AssertMemory(i);
262 if (i->desc==type) return INST(i);
263 /* The following line is a bug. It should be
264 new=SCMUI(); merge parents; destroy(i); return new;
265 It is not provoked because any existing universal atoms to
266 refine up to are filtered out at the RefineInstance function.
267 Therefore the following if never passes.
268 As is, this fails to do the refinement at all if SCMUI passes.
269
270 Another bug is that if this function was ever called with
271 an atom to be refined up to an existing universal, the parents
272 lists would not be properly merged.
273 If any place other than RefineInstance called from RefineClique
274 ever calls this function, this stuff must be fixed.
275
276 In fact, since it never passes, we're going to comment it out.
277 */
278 /*
279 *if (ShortCutMakeUniversalInstance(type)) {
280 * return INST(i);
281 */ /* NOT REACHED */
282 /*}
283 */
284 new = RA_INST(CreateRealInstance(type));
285 /* check value */
286 if (i->assigned > new->assigned){ /* old value is been assigned */
287 new->depth = i->depth;
288 new->assigned = i->assigned;
289 new->value = i->value;
290 }
291 /* check dimensions */
292 if ((dimp = CheckDimensionsMatch(i->dimen,new->dimen))==NULL){
293 FPRINTF(ASCERR,"Dimensional conflict in RefineRealAtom.\n");
294 FPRINTF(ASCERR,"Unable to refine instance.\n");
295 DestroyInstance(INST(new),NULL);
296 return INST(i);
297 }
298 else {
299 new->dimen = dimp;
300 }
301 /* move interface pointer */
302 new->interface_ptr = i->interface_ptr;
303 i->interface_ptr = NULL;
304 if (InterfaceNotify!=NULL)
305 (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
306 /* fix cliques */
307 new->alike_ptr = i->alike_ptr;
308 i->alike_ptr = INST(i);
309 FixCliques(INST(i),INST(new));
310 /* swap parent lists */
311 tmp = new->parents;
312 new->parents = i->parents;
313 i->parents = tmp;
314 /* fix any relations which point to this instance */
315 FixRelations(i,new);
316 /* check children values */
317 if (NumberChildren(INST(i))==NumberChildren(INST(new))) {
318 CheckAtomValuesOne(RA_CHILD(i,0),RA_CHILD(new,0),NumberChildren(INST(i)));
319 } else {
320 CheckAtomValuesTwo(INST(i),INST(new));
321 }
322 ReDirectParents(INST(i),INST(new));
323 /* fix universal stuff */
324 if (GetUniversalFlag(i->desc)) {
325 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
326 }
327 DestroyInstance(INST(i),NULL);
328 AssertMemory(new);
329 return INST(new);
330 }
331
332 static struct Instance *
333 RefineBooleanConstant(struct BooleanConstantInstance *i,
334 struct TypeDescription *type)
335 {
336 assert(MoreRefined(type,i->desc)==type);
337 AssertMemory(i);
338 if (i->desc==type) return INST(i);
339 if (ShortCutMakeUniversalInstance(type)) {
340 /* NOT REACHED */
341 return INST(i);
342 }
343 /* check value */
344 if (!CIASS(i) ) {
345 if (ConstantDefaulted(type) ) {
346 SetBooleanAtomValue(INST(i),GetConstantDefBoolean(type),0);
347 }
348 } else {
349 /* the following will fail if your compiler doesn't use 1 for TRUE */
350 if ((unsigned)BCV(i) != GetConstantDefBoolean(type) ) {
351 FPRINTF(ASCERR,"Value conflict in RefineBooleanConstant.\n");
352 FPRINTF(ASCERR,"Unable to refine instance.\n");
353 return INST(i);
354 }
355 }
356 if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
357 /* don't have to check universal table cause that was already up top */
358 AddUniversalInstance(GetUniversalTable(),type,INST(i));
359 }
360 /* else don't need to change universal table, cause we didn't move */
361 /* no move, so no parent update either */
362 i->desc = type; /* finally somebody make the refinement */
363 return INST(i);
364 }
365
366 static struct Instance *RefineBooleanAtom(struct BooleanAtomInstance *i,
367 struct TypeDescription *type)
368 {
369 register struct BooleanAtomInstance *new;
370 register struct gl_list_t *tmp;
371 assert(MoreRefined(type,i->desc)==type);
372 AssertMemory(i);
373 if (i->desc==type) return INST(i);
374 if (ShortCutMakeUniversalInstance(type)) return INST(i);
375 new = BA_INST(CreateBooleanInstance(type));
376 /* check value */
377 if (i->assigned > new->assigned){ /* old value has been assigned */
378 new->depth = i->depth;
379 new->assigned = i->assigned;
380 new->value = i->value;
381 }
382 /* move interface pointer */
383 new->interface_ptr = i->interface_ptr;
384 i->interface_ptr = NULL;
385 if (InterfaceNotify!=NULL)
386 (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
387 /* fix cliques */
388 new->alike_ptr = i->alike_ptr;
389 i->alike_ptr = INST(i);
390 FixCliques(INST(i),INST(new));
391 tmp = new->parents;
392 new->parents = i->parents;
393 i->parents = tmp;
394 /* fix any logical relation which points to this instance */
395 FixLogRelations(INST(i),INST(new));
396 /* fix any when which points to this instance */
397 FixWhens(INST(i),INST(new));
398 /* check children values */
399 if (NumberChildren(INST(i))==NumberChildren(INST(new)))
400 CheckAtomValuesOne(BA_CHILD(i,0),BA_CHILD(new,0),NumberChildren(INST(i)));
401 else
402 CheckAtomValuesTwo(INST(i),INST(new));
403 ReDirectParents(INST(i),INST(new));
404 /* fix universal stuff */
405 if (GetUniversalFlag(i->desc))
406 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
407 DestroyInstance(INST(i),NULL);
408 AssertMemory(new);
409 return INST(new);
410 }
411
412 static struct Instance
413 *RefineIntegerConstant(struct IntegerConstantInstance *i,
414 struct TypeDescription *type)
415 {
416 assert(MoreRefined(type,i->desc)==type);
417 AssertMemory(i);
418 if (i->desc==type) return INST(i);
419 if (ShortCutMakeUniversalInstance(type)) {
420 /* NOT REACHED */
421 return INST(i);
422 }
423 /* check value */
424 if (!CIASS(i)) {
425 if (ConstantDefaulted(type) ) {
426 SetIntegerAtomValue(INST(i),GetConstantDefInteger(type),0);
427 }
428 } else {
429 if (i->value != GetConstantDefInteger(type) ) {
430 FPRINTF(ASCERR,"Value conflict in RefineIntegerConstant.\n");
431 FPRINTF(ASCERR,"Unable to refine instance.\n");
432 return INST(i);
433 }
434 }
435 if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
436 /* don't have to check universal table cause that was already up top */
437 AddUniversalInstance(GetUniversalTable(),type,INST(i));
438 }
439 /* else don't need to change universal table, cause we didn't move */
440 /* no move, so no parent update either */
441 i->desc = type; /* finally somebody make the refinement */
442 return INST(i);
443 }
444
445 static struct Instance *RefineIntegerAtom(struct IntegerAtomInstance *i,
446 struct TypeDescription *type)
447 {
448 register struct gl_list_t *tmp;
449 register struct IntegerAtomInstance *new;
450 assert(MoreRefined(type,i->desc)==type);
451 AssertMemory(i);
452 if (i->desc==type) return INST(i);
453 if (ShortCutMakeUniversalInstance(type)) return INST(i);
454 new = IA_INST(CreateIntegerInstance(type));
455 /* check value */
456 if (i->assigned > new->assigned){ /* old value is been assigned */
457 new->depth = i->depth;
458 new->assigned = i->assigned;
459 new->value = i->value;
460 }
461 /* move interface pointer */
462 new->interface_ptr = i->interface_ptr;
463 i->interface_ptr = NULL;
464 if (InterfaceNotify!=NULL)
465 (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
466 /* fix cliques */
467 new->alike_ptr = i->alike_ptr;
468 i->alike_ptr = INST(i);
469 FixCliques(INST(i),INST(new));
470 tmp = new->parents;
471 new->parents = i->parents;
472 i->parents = tmp;
473 /* fix any when which points to this instance */
474 FixWhens(INST(i),INST(new));
475 /* check children values */
476 if (NumberChildren(INST(i))==NumberChildren(INST(new)))
477 CheckAtomValuesOne(IA_CHILD(i,0),IA_CHILD(new,0),NumberChildren(INST(i)));
478 else
479 CheckAtomValuesTwo(INST(i),INST(new));
480 ReDirectParents(INST(i),INST(new));
481 /* fix universal stuff */
482 if (GetUniversalFlag(i->desc))
483 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
484 DestroyInstance(INST(i),NULL);
485 AssertMemory(new);
486 return INST(new);
487 }
488
489 /* this function REASSIGNS a set value. since when is that legal? ! */
490 static struct Instance *RefineSet(struct SetAtomInstance *i,
491 struct TypeDescription *type)
492 {
493 register struct gl_list_t *tmp;
494 register struct SetAtomInstance *new;
495 assert(MoreRefined(type,i->desc)==type);
496 AssertMemory(i);
497 if (i->desc==type) return INST(i);
498 if (ShortCutMakeUniversalInstance(type)) return INST(i);
499 new = SA_INST(CreateSetInstance(type,i->int_set));
500 /* check value */
501 if (i->list!=NULL){
502 new->list = i->list;
503 i->list = NULL;
504 }
505 /* move interface pointer */
506 new->interface_ptr = i->interface_ptr;
507 i->interface_ptr = NULL;
508 if (InterfaceNotify!=NULL)
509 (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
510 /* fix cliques */
511 new->alike_ptr = i->alike_ptr;
512 i->alike_ptr = INST(i);
513 FixCliques(INST(i),INST(new));
514 tmp = new->parents;
515 new->parents = i->parents;
516 i->parents = tmp;
517 /* check children values */
518 if (NumberChildren(INST(i))==NumberChildren(INST(new)))
519 CheckAtomValuesOne(SA_CHILD(i,0),SA_CHILD(new,0),NumberChildren(INST(i)));
520 else
521 CheckAtomValuesTwo(INST(i),INST(new));
522 ReDirectParents(INST(i),INST(new));
523 /* fix universal stuff */
524 if (GetUniversalFlag(i->desc))
525 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
526 DestroyInstance(INST(i),NULL);
527 AssertMemory(new);
528 return INST(new);
529 }
530
531 static struct Instance *RefineSymbolConstant(struct SymbolConstantInstance *i,
532 struct TypeDescription *type)
533 {
534 assert(MoreRefined(type,i->desc)==type);
535 AssertMemory(i);
536 if (i->desc==type) return INST(i);
537 if (ShortCutMakeUniversalInstance(type)) {
538 /* NOT REACHED*/
539 return INST(i);
540 }
541 if (i->value==NULL ) {
542 if (ConstantDefaulted(type) ) {
543 SetSymbolAtomValue(INST(i),GetConstantDefSymbol(type));
544 }
545 } else {
546 if ( SYMC_INST(i)->value != GetConstantDefSymbol(type) ) {
547 FPRINTF(ASCERR,"Value conflict in RefineSymbolConstant.\n");
548 FPRINTF(ASCERR,"Unable to refine instance.\n");
549 return INST(i);
550 }
551 }
552 if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
553 /* don't have to check universal table cause that was already up top */
554 AddUniversalInstance(GetUniversalTable(),type,INST(i));
555 }
556 i->desc = type;
557 return INST(i);
558 }
559
560 static struct Instance *RefineSymbolAtom(struct SymbolAtomInstance *i,
561 struct TypeDescription *type)
562 {
563 register struct gl_list_t *tmp;
564 register struct SymbolAtomInstance *new;
565 assert(MoreRefined(type,i->desc)==type);
566 AssertMemory(i);
567 if (i->desc==type) return INST(i);
568 if (ShortCutMakeUniversalInstance(type)) return INST(i);
569 new = SYMA_INST(CreateSymbolInstance(type));
570 /* check value */
571 if (i->value!=NULL){
572 new->value = i->value;
573 }
574 /* move interface pointer */
575 new->interface_ptr = i->interface_ptr;
576 i->interface_ptr = NULL;
577 if (InterfaceNotify!=NULL)
578 (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
579 /* fix cliques */
580 new->alike_ptr = i->alike_ptr;
581 i->alike_ptr = INST(i);
582 FixCliques(INST(i),INST(new));
583 tmp = new->parents;
584 new->parents = i->parents;
585 i->parents = tmp;
586 /* fix any when which points to this instance */
587 FixWhens(INST(i),INST(new));
588 /* check children values */
589 if (NumberChildren(INST(i))==NumberChildren(INST(new)))
590 CheckAtomValuesOne(SYMA_CHILD(i,0),SYMA_CHILD(new,0),
591 NumberChildren(INST(i)));
592 else
593 CheckAtomValuesTwo(INST(i),INST(new));
594 ReDirectParents(INST(i),INST(new));
595 /* fix universal stuff */
596 if (GetUniversalFlag(i->desc))
597 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
598 DestroyInstance(INST(i),NULL);
599 AssertMemory(new);
600 return INST(new);
601 }
602
603 /*
604 * This function morphs the type and expands the bit list if the
605 * refined to type is a new UNIVERSAL or a non-UNIVERSAL type >
606 * the type of i. If the new type requires more children,
607 * i is realloc'd.
608 * If needed, adds the inst to the pending list again.
609 * Does not reinvoke the instantiator (which should be obvious).
610 *
611 * around UNIVERSAL an arginst !=NULL needs work. fix me.
612 */
613 static
614 struct Instance *RefineModel(struct ModelInstance *i,
615 struct TypeDescription *type,
616 struct ModelInstance *arginst)
617 {
618 struct TypeDescription *oldtype;
619 register unsigned long new_length,old_length;
620 register struct ModelInstance *result;
621 assert(MoreRefined(type,i->desc)==type);
622 AssertMemory(i);
623 AssertMemory(type);
624 if (i->desc==type) {
625 return INST(i);
626 }
627 /* we assume at this point that the sanity of the refinement
628 * move has been checked.
629 */
630 oldtype = i->desc;
631 /* pop i into pendings if needed */
632 new_length = gl_length(GetList(GetStatementList(type)));
633 if (new_length > BLength(i->executed)){
634 i->executed = ExpandFBList(i->executed,new_length);
635 if (!InstanceInList(INST(i))) {
636 /* i is necessarily a model instance at this point */
637 AddBelow(NULL,INST(i));
638 /* add PENDING model */
639 }
640 }
641 new_length = ChildListLen(GetChildList(type));
642 old_length = ChildListLen(GetChildList(i->desc));
643 if (new_length > old_length){
644 /* resize the instance */
645 result = MOD_INST(ascrealloc((char *)i,
646 (unsigned)sizeof(struct ModelInstance)+
647 (unsigned)new_length*
648 (unsigned)sizeof(struct Instance *)));
649 if (result!=i) {
650 /* if realloc moved the instance, need to update all connections to
651 * the instance from before it was refined to point at the new memory.
652 */
653 PendingInstanceRealloced(INST(i),INST(result)); /* change pending list */
654 if (InterfaceNotify!=NULL)
655 (*InterfaceNotify)(result->interface_ptr,INST(i),INST(result));
656 /* fix external relations variables */
657 FixExternalVars(INST(i),INST(result));
658 /* fix whens */
659 FixWhensForRefinement(INST(i),INST(result));
660 ReDirectParents(INST(i),INST(result));
661 ReDirectChildren(INST(i),INST(result));
662 /* fix cliques */
663 FixCliques(INST(i),INST(result));
664 /* fix universal stuff */
665 if (GetUniversalFlag(result->desc)) {
666 ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(result));
667 }
668 }
669 /* init spaces of expanded instance to NULL */
670 ZeroNewChildrenEntries(MOD_CHILD(result,old_length),new_length-old_length);
671 ReorderChildrenPtrs(MOD_CHILD(result,0),
672 GetChildList(result->desc),
673 GetChildList(type),
674 old_length,
675 new_length);
676 result->desc = type;
677 ReConfigureInstFromArgs(INST(result),INST(arginst));
678 } else {
679 result = i;
680 result->desc = type;
681 }
682 /* add new universal type entry */
683 if (GetUniversalFlag(type)) {
684 AddUniversalInstance(GetUniversalTable(),type,INST(result));
685 }
686 /* fix the reference counts in the library */
687 DeleteTypeDesc(oldtype);
688 CopyTypeDesc(type);
689 AssertMemory(result);
690 return INST(result);
691 }
692
693
694 struct Instance *RefineInstance(struct Instance *i,
695 struct TypeDescription *type,
696 struct Instance *arginst)
697 {
698 struct TypeDescription *desc;
699 assert((i!=NULL)&&(type!=NULL));
700 AssertMemory(i);
701 /* oy, arginst will need some fancy footwork here. fix me */
702 if (GetUniversalFlag(type)&&
703 LookupInstance(GetUniversalTable(),type)){
704 desc = InstanceTypeDesc(i);
705 if (GetUniversalFlag(desc)){
706 ChangeUniversalInstance(GetUniversalTable(),
707 i,
708 LookupInstance(GetUniversalTable(),type));
709 }
710 i = MergeInstances(i,LookupInstance(GetUniversalTable(),type));
711 PostMergeCheck(i);
712 return i;
713 }
714 /* if the above if/Merge are not there, then bugs in the Refine<type>
715 * functions switched below will destroy type and memory integrity.
716 * See RefineRealAtom for details.
717 * No universal instance matching type both can and does exist .
718 */
719 switch(i->t) {
720 case MODEL_INST:
721 return RefineModel(MOD_INST(i),type,MOD_INST(arginst));
722 case REAL_ATOM_INST:
723 return RefineRealAtom(RA_INST(i),type);
724 case BOOLEAN_ATOM_INST:
725 return RefineBooleanAtom(BA_INST(i),type);
726 case INTEGER_ATOM_INST:
727 return RefineIntegerAtom(IA_INST(i),type);
728 case SET_ATOM_INST:
729 return RefineSet(SA_INST(i),type);
730 case SYMBOL_ATOM_INST:
731 return RefineSymbolAtom(SYMA_INST(i),type);
732 case REAL_CONSTANT_INST:
733 return RefineRealConstant(RC_INST(i),type);
734 case BOOLEAN_CONSTANT_INST:
735 return RefineBooleanConstant(BC_INST(i),type);
736 case INTEGER_CONSTANT_INST:
737 return RefineIntegerConstant(IC_INST(i),type);
738 case SYMBOL_CONSTANT_INST:
739 return RefineSymbolConstant(SYMC_INST(i),type);
740 case ARRAY_INT_INST:
741 case ARRAY_ENUM_INST:
742 case REL_INST:
743 case LREL_INST:
744 case WHEN_INST:
745 case SIM_INST:
746 /* at the current time these are meaningless */
747 Asc_Panic(2, NULL,
748 "At the current time these refining"
749 " an array,when or relation is undefined");
750 case REAL_INST:
751 case INTEGER_INST:
752 case BOOLEAN_INST:
753 case SET_INST:
754 case SYMBOL_INST:
755 case DUMMY_INST:
756 Asc_Panic(2, NULL,
757 "It is illegal to call RefineInstance on a fundamental atom.");
758 default:
759 Asc_Panic(2, NULL, "RefineInstance called on unknown instance type.\n");
760 }
761 exit(2);/* NOT REACHED. Needed to keep gcc from whining */
762 }
763
764
765 struct Instance *RefineClique(struct Instance *i,
766 struct TypeDescription *type,
767 struct Instance *arginst)
768 {
769 struct Instance *ptr;
770 AssertMemory(i);
771 /* assert that it is conformable and that type is more refined */
772 assert(MoreRefined(InstanceTypeDesc(i),type)==type);
773 if (arginst != NULL) {
774 assert(MoreRefined(InstanceTypeDesc(arginst),type)==type);
775 }
776 ptr = i = RefineInstance(i,type,arginst);
777 while ( (ptr = NextCliqueMember(ptr)) != i){
778 assert(ptr!=NULL);
779 ptr = RefineInstance(ptr,type,arginst);
780 }
781 return i;
782 }
783

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