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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 97 - (show annotations) (download) (as text)
Fri Dec 9 03:49:19 2005 UTC (14 years, 9 months ago) by jds
File MIME type: text/x-csrc
File size: 34420 byte(s)
Minor fixes to:
 - continue killing compiler warnings on gcc & msvc 
 - start working on function/data pointer mismatches
 - documentation tweaks

Fixed ascMalloc.c memory logging problems.  This has not been tested on linux/unix.  If it fails to compile, please revert to the previous version and let me know.
1 /*
2 * Ascend Instance Tree Type Implementation
3 * by Tom Epperly 9/3/89
4 * Version: $Revision: 1.18 $
5 * Version control file: $RCSfile: copyinst.c,v $
6 * Date last modified: $Date: 1998/03/17 22:08:28 $
7 * Last modified by: $Author: ballan $
8 *
9 * This file is part of the Ascend Language Interpreter.
10 *
11 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
12 *
13 * The Ascend Language Interpreter is free software; you can redistribute
14 * it and/or modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) any later version.
17 *
18 * The Ascend Language Interpreter is distributed in hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with the program; if not, write to the Free Software Foundation,
25 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
26 * COPYING.
27 *
28 */
29 #include <stdarg.h>
30 #include "utilities/ascConfig.h"
31 #include "utilities/ascMalloc.h"
32 #include "utilities/ascPanic.h"
33 #include "general/pool.h"
34 #include "general/list.h"
35 #include "general/dstring.h"
36 #include "compiler/compiler.h"
37 #include "compiler/bit.h"
38 #include "compiler/symtab.h"
39 #include "compiler/fractions.h"
40 #include "compiler/dimen.h"
41 #include "compiler/functype.h"
42 #include "compiler/types.h"
43 #include "compiler/childinfo.h"
44 #include "compiler/child.h"
45 #include "compiler/type_desc.h"
46 #include "compiler/instance_enum.h"
47 #include "compiler/instance_name.h"
48 #include "compiler/instance_types.h"
49 #include "compiler/instance_io.h"
50 #include "compiler/instmacro.h"
51 #include "compiler/visitinst.h"
52 #include "compiler/parentchild.h"
53 #include "compiler/extinst.h"
54 #include "compiler/instquery.h"
55 #include "compiler/linkinst.h"
56 #include "compiler/destroyinst.h"
57 #include "compiler/arrayinst.h"
58 #include "compiler/mathinst.h"
59 #include "compiler/createinst.h"
60 #include "compiler/refineinst.h"
61 #include "compiler/atomvalue.h"
62 #include "compiler/atomsize.h"
63 #include "compiler/check.h"
64 #include "compiler/dump.h"
65 #include "compiler/prototype.h"
66 #include "compiler/pending.h"
67 #include "compiler/find.h"
68 #include "compiler/relation_type.h"
69 #include "compiler/relation.h"
70 #include "compiler/logical_relation.h"
71 #include "compiler/logrelation.h"
72 #include "compiler/relation_util.h"
73 #include "compiler/logrel_util.h"
74 #include "compiler/rel_common.h"
75 #include "compiler/case.h"
76 #include "compiler/when_util.h"
77 #include "compiler/universal.h"
78 #include "general/pool.h"
79 #include "compiler/tmpnum.h"
80 #include "compiler/cmpfunc.h"
81 #include "compiler/setinstval.h"
82 #include "compiler/copyinst.h"
83
84 #ifndef lint
85 static CONST char CopyInstModuleID[] = "$Id: copyinst.c,v 1.18 1998/03/17 22:08:28 ballan Exp $";
86 #endif
87
88
89 /*
90 * This function simply makes a first pass at determining
91 * whether the instance is a universal instance. It returns
92 * non NULL, if TRUE.
93 */
94 struct Instance *ShortCutMakeUniversalInstance(struct TypeDescription *type)
95 {
96 struct Instance *result;
97 if (GetUniversalFlag(type)&&
98 (0 != (result=LookupInstance(GetUniversalTable(),type)))) {
99 return result;
100 } else {
101 return NULL;
102 }
103 }
104
105 /*
106 * This function simply makes a first pass at determining
107 * whether a prototype of the instance exists. It returns
108 * non NULL, if TRUE.
109 */
110 struct Instance *ShortCutProtoInstance(struct TypeDescription *type)
111 {
112 struct Instance *result, *proto;
113
114 result = LookupPrototype(GetName(type));
115 if (result) {
116 proto = CopyInstance(result);
117 return proto;
118 } else {
119 return NULL;
120 }
121 }
122
123 /*********************************************************************\
124 Copy Instance code.
125 \*********************************************************************/
126
127 void CheckChildCopies(register unsigned long int num,
128 register struct Instance **clist)
129 {
130 register unsigned long c;
131 for(c=0;c<num;c++) {
132 if ((clist[c]->t==SET_INST)&&(S_INST(clist[c])->list!=NULL)) {
133 S_INST(clist[c])->list = CopySet(S_INST(clist[c])->list);
134 }
135 }
136 }
137
138 void RedoChildPointers(unsigned long int num,
139 struct Instance *newparent,
140 struct Instance **newchildptrs,
141 CONST struct Instance *oldparent,
142 struct Instance * CONST *oldchildptrs)
143 {
144 while (num > 0) {
145 *newchildptrs = INST((unsigned long)newparent+
146 (unsigned long)(*oldchildptrs)-
147 (unsigned long)oldparent);
148 newchildptrs++;
149 oldchildptrs++;
150 num--;
151 }
152 }
153
154 /*
155 * mem copy of a REAL_ATOM_INSTANCE or REAL_CONSTANT_INSTANCE.
156 */
157 static
158 struct Instance *CopyReal(CONST struct Instance *i)
159 {
160 if (IsAtomicInstance(i)) {
161 register struct RealAtomInstance *src,*result;
162 register unsigned long size;
163 AssertMemory(i);
164 src = RA_INST(i);
165 size = GetByteSize(src->desc);
166 result = RA_INST(ascmalloc((unsigned)size));
167 ascbcopy((char *)src,(char *)result,(int)size);
168 result->parents = gl_create(AVG_PARENTS);
169 result->alike_ptr = INST(result);
170 result->relations = NULL; /* initially the copy isn't in any relations */
171 CopyTypeDesc(result->desc);
172 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
173 INST(result),RA_CHILD(result,0),
174 i,RA_CHILD(i,0));
175 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
176 RA_CHILD(result,0));
177 AssertMemory(result);
178 return INST(result);
179 } else {
180 register struct RealConstantInstance *src,*result;
181 register unsigned long size;
182 AssertMemory(i);
183 src = RC_INST(i);
184 size = GetByteSize(src->desc);
185 result = RC_INST(ascmalloc((unsigned)size));
186 ascbcopy((char *)src,(char *)result,(int)size);
187 result->parents = gl_create(AVG_CONSTANT_PARENTS);
188 result->alike_ptr = INST(result);
189 CopyTypeDesc(result->desc);
190 AssertMemory(result);
191 return INST(result);
192 }
193 }
194
195 /*
196 * mem copy of a INTEGER_ATOM_INSTANCE or INTEGER_CONSTANT_INSTANCE.
197 */
198 static
199 struct Instance *CopyInteger(CONST struct Instance *i)
200 {
201 if (IsAtomicInstance(i)) {
202 register struct IntegerAtomInstance *src,*result;
203 register unsigned long size;
204
205 AssertMemory(i);
206 src = IA_INST(i);
207 size = GetByteSize(src->desc);
208 result = IA_INST(ascmalloc((unsigned)size));
209 ascbcopy((char *)src,(char *)result,(int)size);
210 result->parents = gl_create(AVG_PARENTS);
211 result->alike_ptr = INST(result);
212 result->whens = NULL;
213 CopyTypeDesc(result->desc);
214 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
215 INST(result),IA_CHILD(result,0),
216 i,IA_CHILD(i,0));
217 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
218 IA_CHILD(result,0));
219 AssertMemory(result);
220 return INST(result);
221 } else {
222 register struct IntegerConstantInstance *src,*result;
223 register unsigned long size;
224
225 AssertMemory(i);
226 src = IC_INST(i);
227 size = GetByteSize(src->desc);
228 result = IC_INST(ascmalloc((unsigned)size));
229 ascbcopy((char *)src,(char *)result,(int)size);
230 result->parents = gl_create(AVG_ICONSTANT_PARENTS);
231 result->alike_ptr = INST(result);
232 result->whens = NULL;
233 CopyTypeDesc(result->desc);
234 AssertMemory(result);
235 return INST(result);
236 }
237 }
238
239 /*
240 * mem copy of a BOOLEAN_ATOM_INSTANCE or BOOLEAN_CONSTANT_INSTANCE.
241 */
242 static
243 struct Instance *CopyBoolean(CONST struct Instance *i)
244 {
245 if (IsAtomicInstance(i)) {
246 register struct BooleanAtomInstance *src,*result;
247 register unsigned long size;
248 AssertMemory(i);
249 src = BA_INST(i);
250 size = GetByteSize(src->desc);
251 result = BA_INST(ascmalloc((unsigned)size));
252 ascbcopy((char *)src,(char *)result,(int)size);
253 result->parents = gl_create(AVG_PARENTS);
254 result->alike_ptr = INST(result);
255 result->logrelations = NULL;
256 result->whens = NULL;
257 /* initially the copy isn't in any logical relation or when */
258 CopyTypeDesc(result->desc);
259 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
260 INST(result),BA_CHILD(result,0),
261 i,BA_CHILD(i,0));
262 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
263 BA_CHILD(result,0));
264 AssertMemory(result);
265 return INST(result);
266 } else {
267 register struct BooleanConstantInstance *src,*result;
268 register unsigned long size;
269 AssertMemory(i);
270 src = BC_INST(i);
271 size = GetByteSize(src->desc);
272 result = BC_INST(ascmalloc((unsigned)size));
273 ascbcopy((char *)src,(char *)result,(int)size);
274 result->parents = gl_create(AVG_PARENTS);
275 result->alike_ptr = INST(result);
276 result->whens = NULL;
277 CopyTypeDesc(result->desc);
278 AssertMemory(result);
279 return INST(result);
280 }
281 }
282
283 static
284 struct Instance *CopySetInst(CONST struct Instance *i)
285 {
286 register struct SetAtomInstance *src, *result;
287 register unsigned long size;
288 AssertMemory(i);
289 src = SA_INST(i);
290 size = GetByteSize(src->desc);
291 result = SA_INST(ascmalloc((unsigned)size));
292 ascbcopy((char *)src,(char *)result,(int)size);
293 if (src->list!=NULL)
294 result->list = CopySet(src->list);
295 result->parents = gl_create(AVG_PARENTS);
296 result->alike_ptr = INST(result);
297 CopyTypeDesc(result->desc);
298 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
299 INST(result),SA_CHILD(result,0),
300 i,SA_CHILD(i,0));
301 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
302 SA_CHILD(result,0));
303 AssertMemory(result);
304 return INST(result);
305 }
306
307 /*
308 * mem copy of a SYMBOL_ATOM_INSTANCE or SYMBOL_CONSTANT_INSTANCE.
309 */
310 static
311 struct Instance *CopySymbolInst(CONST struct Instance *i)
312 {
313 if (IsAtomicInstance(i)) {
314 register struct SymbolAtomInstance *src,*result;
315 register unsigned long size;
316 AssertMemory(i);
317 src = SYMA_INST(i);
318 size = GetByteSize(src->desc);
319 result = SYMA_INST(ascmalloc((unsigned)size));
320 ascbcopy((char *)src,(char *)result,(int)size);
321 result->parents = gl_create(AVG_PARENTS);
322 result->alike_ptr = INST(result);
323 result->whens = NULL;
324 CopyTypeDesc(result->desc);
325 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
326 INST(result),SYMA_CHILD(result,0),
327 i,SYMA_CHILD(i,0));
328 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
329 SYMA_CHILD(result,0));
330 AssertMemory(result);
331 return INST(result);
332 } else {
333 register struct SymbolConstantInstance *src,*result;
334 register unsigned long size;
335 AssertMemory(i);
336 src = SYMC_INST(i);
337 size = GetByteSize(src->desc);
338 result = SYMC_INST(ascmalloc((unsigned)size));
339 ascbcopy((char *)src,(char *)result,(int)size);
340 result->parents = gl_create(AVG_ICONSTANT_PARENTS);
341 result->alike_ptr = INST(result);
342 result->whens = NULL;
343 CopyTypeDesc(result->desc);
344 AssertMemory(result);
345 return INST(result);
346 }
347 }
348
349 static
350 struct Instance *CopyRelationInst(CONST struct Instance *i)
351 {
352 register struct RelationInstance *src,*result;
353 register unsigned long size;
354 AssertMemory(i);
355 src = RELN_INST(i);
356 size = GetByteSize(src->desc);
357 result = RELN_INST(ascmalloc((unsigned)size));
358 ascbcopy((char *)src,(char *)result,(int)size);
359 result->parent[0] = NULL;
360 result->parent[1] = NULL;
361 result->whens = NULL;
362 result->logrels = NULL;
363 result->anon_flags = 0x0;
364 CopyTypeDesc(result->desc);
365 result->ptr = NULL;
366
367 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
368 INST(result),REL_CHILD(result,0),
369 i,REL_CHILD(i,0));
370 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
371 REL_CHILD(result,0));
372 AssertMemory(result);
373 return INST(result);
374 }
375
376 static
377 struct Instance *CopyLogRelInst(CONST struct Instance *i)
378 {
379 register struct LogRelInstance *src,*result;
380 register unsigned long size;
381 AssertMemory(i);
382 src = LRELN_INST(i);
383 size = GetByteSize(src->desc);
384 result = LRELN_INST(ascmalloc((unsigned)size));
385 ascbcopy((char *)src,(char *)result,(int)size);
386 result->parent[0] = NULL;
387 result->parent[1] = NULL;
388 result->whens = NULL;
389 result->logrels = NULL;
390 result->anon_flags = 0x0;
391 CopyTypeDesc(result->desc);
392 result->ptr = NULL;
393 RedoChildPointers(ChildListLen(GetChildList(result->desc)),
394 INST(result),LREL_CHILD(result,0),
395 i,LREL_CHILD(i,0));
396 CheckChildCopies(ChildListLen(GetChildList(result->desc)),
397 LREL_CHILD(result,0));
398 AssertMemory(result);
399 return INST(result);
400 }
401
402
403 static
404 struct Instance *CopyWhenInst(CONST struct Instance *i)
405 {
406 register struct WhenInstance *src,*result;
407 register unsigned long size;
408 AssertMemory(i);
409 src = W_INST(i);
410 size = sizeof(struct WhenInstance);
411 result = W_INST(ascmalloc((unsigned)size));
412 ascbcopy((char *)src,(char *)result,(int)size);
413 result->parent[0] = NULL;
414 result->parent[1] = NULL;
415 CopyTypeDesc(result->desc);
416 result->whens = NULL;
417 result->cases = NULL;
418 result->bvar = NULL;
419 AssertMemory(result);
420 return INST(result);
421 }
422
423 /*
424 * We dont use bcopy here so that we have to make sure
425 * that we individually copy the relevant fields from
426 * the source instance.
427 */
428 static
429 struct Instance *CopyModel(CONST struct Instance *i)
430 {
431 register struct ModelInstance *mod,*result;
432 register unsigned long num_children;
433 register struct TypeDescription *type;
434 AssertMemory(i);
435 mod = MOD_INST(i);
436 type = mod->desc;
437 CopyTypeDesc(type);
438 num_children = ChildListLen(GetChildList(type));
439 result = MOD_INST(ascmalloc((unsigned)sizeof(struct ModelInstance)+
440 (unsigned)num_children*
441 (unsigned)sizeof(struct Instance *)));
442 result->t = MODEL_INST;
443 result->pending_entry = NULL;
444 result->interface_ptr = mod->interface_ptr;
445 result->parents = gl_create(gl_length(mod->parents));
446 result->whens = NULL;
447 result->desc = type;
448 result->alike_ptr = INST(result);
449 result->visited = 0;
450 result->tmp_num = 0;
451 result->anon_flags = 0x0;
452 result->executed = CopyBList(mod->executed);
453 ZeroNewChildrenEntries(MOD_CHILD(result,0),num_children);
454 AssertMemory(result);
455 return INST(result);
456 }
457
458 static struct gl_list_t *CopyArrayChildPtrs(struct gl_list_t *list)
459 {
460 register struct gl_list_t *result;
461 register unsigned long length,c;
462 register struct ArrayChild *new,*src;
463 if (list!=NULL){
464 length = gl_length(list);
465 if (length) {
466 result = gl_create(length);
467 for(c=1;c<=length;c++) {
468 src = (struct ArrayChild *)gl_fetch(list,c);
469 new = MALLOCPOOLAC;
470 *new = *src;
471 new->inst = NULL;
472 gl_append_ptr(result,(VOIDPTR)new);
473 }
474 gl_set_sorted(result, TRUE); /* because the originals were, by name */
475 return result;
476 } else {
477 return gl_create(AVG_ARY_CHILDREN);
478 }
479 } else {
480 return NULL;
481 }
482 }
483
484 static struct Instance *CopyArray(CONST struct Instance *i)
485 {
486 register struct ArrayInstance *ary,*result;
487 AssertMemory(i);
488 ary = ARY_INST(i);
489 result = ARY_INST(ascmalloc(sizeof(struct ArrayInstance)));
490 result->t = ary->t;
491 result->pending_entry = NULL;
492 result->desc = ary->desc;
493 CopyTypeDesc(result->desc);
494 result->indirected = ary->indirected;
495 result->visited = 0;
496 result->tmp_num = 0;
497 result->parents = gl_create(AVG_PARENTS);
498 result->children = CopyArrayChildPtrs(ary->children);
499 AssertMemory(result);
500 return INST(result);
501 }
502
503
504 /*
505 * This is just a preprocessing function. The work of doing
506 * sanity checking of the incidence lists, and for
507 * making the variable aware of the RELINST is that of
508 * CopyRelationVarList in relation.[ch]
509 */
510 static
511 void BuildRelationVarList(CONST struct Instance *src,
512 struct gl_list_t *dest_list,
513 struct gl_list_t *varlist)
514 {
515 struct Instance *i,*ptr;
516 CONST struct gl_list_t *src_varlist;
517 CONST struct relation *rel;
518 unsigned long len,c,copynum;
519
520 assert(src->t==REL_INST);
521
522 rel = RELN_INST(src)->ptr;
523 src_varlist = RelationVarList(rel);
524 if (!src_varlist) return;
525
526 len = gl_length(src_varlist);
527 for (c=1;c<=len;c++) {
528 i = (struct Instance *)gl_fetch(src_varlist,c);
529 copynum = GetTmpNum(i);
530 ptr = (struct Instance *)gl_fetch(dest_list,copynum);
531 gl_append_ptr(varlist,(VOIDPTR)ptr);
532 }
533 }
534
535 static
536 void BuildLogRelBVarList(CONST struct Instance *src,
537 struct gl_list_t *dest_list,
538 struct gl_list_t *bvarlist)
539 {
540 struct Instance *i,*ptr;
541 CONST struct gl_list_t *src_bvarlist;
542 CONST struct logrelation *lrel;
543 unsigned long len,c,copynum;
544
545 assert(src->t==LREL_INST);
546
547 lrel = LRELN_INST(src)->ptr;
548 src_bvarlist = LogRelBoolVarList(lrel);
549 if (!src_bvarlist) return;
550
551 len = gl_length(src_bvarlist);
552 for (c=1;c<=len;c++) {
553 i = (struct Instance *)gl_fetch(src_bvarlist,c);
554 copynum = GetTmpNum(i);
555 ptr = (struct Instance *)gl_fetch(dest_list,copynum);
556 gl_append_ptr(bvarlist,(VOIDPTR)ptr);
557 }
558 }
559
560
561 static
562 void BuildLogRelSatRelList(CONST struct Instance *src,
563 struct gl_list_t *dest_list,
564 struct gl_list_t *rellist)
565 {
566 struct Instance *i,*ptr;
567 CONST struct gl_list_t *src_rellist;
568 CONST struct logrelation *lrel;
569 unsigned long len,c,copynum;
570
571 assert(src->t==LREL_INST);
572
573 lrel = LRELN_INST(src)->ptr;
574 src_rellist = LogRelSatRelList(lrel);
575 if (!src_rellist) return;
576
577 len = gl_length(src_rellist);
578 for (c=1;c<=len;c++) {
579 i = (struct Instance *)gl_fetch(src_rellist,c);
580 copynum = GetTmpNum(i);
581 ptr = (struct Instance *)gl_fetch(dest_list,copynum);
582 gl_append_ptr(rellist,(VOIDPTR)ptr);
583 }
584 }
585
586
587 static void BuildWhenVarList(CONST struct Instance *src,
588 struct gl_list_t *dest_list,
589 struct gl_list_t *bvarlist)
590 {
591 struct Instance *i,*ptr,*dest;
592 struct gl_list_t *src_bvarlist;
593 unsigned long len,c,copynum;
594
595 assert(src->t==WHEN_INST);
596 copynum = GetTmpNum(src);
597 dest = (struct Instance *)gl_fetch(dest_list,copynum);
598
599 src_bvarlist = GetInstanceWhenVars(src);
600 if (!src_bvarlist) return;
601 len = gl_length(src_bvarlist);
602
603 for (c=1;c<=len;c++) {
604 i = (struct Instance *)gl_fetch(src_bvarlist,c);
605 copynum = GetTmpNum(i);
606 ptr = (struct Instance *)gl_fetch(dest_list,copynum);
607 gl_append_ptr(bvarlist,(VOIDPTR)ptr);
608 }
609 W_INST(dest)->bvar = CopyWhenBVarList(dest,bvarlist);
610 }
611
612
613 static
614 struct gl_list_t *BuildWhenCasesRefList(struct Instance *dest,
615 struct gl_list_t *srcref_list,
616 struct gl_list_t *dest_list)
617 {
618 struct Instance *i,*ptr;
619 struct gl_list_t *destref_list;
620 unsigned long ref,lref,copynum;
621
622 lref = gl_length(srcref_list);
623 destref_list = gl_create(lref);
624 for (ref=1;ref<=lref;lref++) {
625 i = (struct Instance *)gl_fetch(srcref_list,ref);
626 copynum = GetTmpNum(i);
627 ptr = (struct Instance *)gl_fetch(dest_list,copynum);
628 gl_append_ptr(destref_list,(VOIDPTR)ptr);
629 AddWhen(ptr,dest);
630 }
631 return destref_list;
632 }
633
634
635 static void BuildWhenCasesList(CONST struct Instance *src,
636 struct gl_list_t *dest_list)
637 {
638 struct Instance *dest;
639 struct gl_list_t *src_caselist,*srcref_list;
640 struct gl_list_t *destref_list,*caselist;
641 struct Case *src_case,*dest_case;
642 unsigned long len,c,copynum;
643
644 assert(src->t==WHEN_INST);
645 copynum = GetTmpNum(src);
646 dest = (struct Instance *)gl_fetch(dest_list,copynum);
647
648 src_caselist = GetInstanceWhenCases(src);
649 if (!src_caselist) return;
650 len = gl_length(src_caselist);
651 caselist = gl_create(len);
652
653 for (c=1;c<=len;c++) {
654 src_case = (struct Case *)gl_fetch(src_caselist,c);
655 dest_case = CreateCase(GetCaseValues(src_case),NULL);
656 srcref_list = GetCaseReferences(src_case);
657 destref_list = BuildWhenCasesRefList(dest,srcref_list,dest_list);
658 SetCaseReferences(dest_case,destref_list);
659 gl_append_ptr(caselist,(VOIDPTR)dest_case);
660 }
661 W_INST(dest)->cases = caselist;
662 }
663
664
665 static
666 void CopyRelationStructures(struct gl_list_t *src_list,
667 struct gl_list_t *dest_list,
668 enum Copy_enum copy_relns)
669 {
670 CONST struct Instance *src;
671 struct Instance *dest;
672 struct gl_list_t *scratch;
673 struct relation *rel = NULL;
674 enum Expr_enum type;
675 unsigned long len,c,copynum;
676
677 len = gl_length(src_list);
678 scratch = gl_create(100L);
679
680 for (c=1;c<=len;c++) {
681 src = (CONST struct Instance *)gl_fetch(src_list,c);
682 if (src->t!=REL_INST)
683 continue;
684 BuildRelationVarList(src,dest_list,scratch);
685 copynum = GetTmpNum(src);
686 dest = (struct Instance *)gl_fetch(dest_list,copynum);
687 switch (copy_relns) {
688 case c_reference:
689 rel = CopyRelationByReference(src,dest,scratch);
690 break;
691 case c_tomodify:
692 rel = CopyRelationToModify(src,dest,scratch);
693 break;
694 default:
695 Asc_Panic(2, NULL, "Invalid type in CopyRelationStructures\n");
696 exit(2);
697 }
698 type = GetInstanceRelationType(src);
699 SetInstanceRelation(dest,rel,type);
700 gl_reset(scratch);
701 }
702 gl_destroy(scratch);
703 }
704
705
706 static
707 void CopyLogRelStructures(struct gl_list_t *src_list,
708 struct gl_list_t *dest_list,
709 enum Copy_enum copy_lrelns)
710 {
711 CONST struct Instance *src;
712 struct Instance *dest;
713 struct gl_list_t *varlist;
714 struct gl_list_t *rellist;
715 struct logrelation *lrel;
716 unsigned long len,c,copynum;
717
718 len = gl_length(src_list);
719 varlist = gl_create(100L);
720 rellist = gl_create(100L);
721
722 for (c=1;c<=len;c++) {
723 src = (CONST struct Instance *)gl_fetch(src_list,c);
724 if (src->t!=LREL_INST)
725 continue;
726 BuildLogRelBVarList(src,dest_list,varlist);
727 BuildLogRelSatRelList(src,dest_list,rellist);
728 copynum = GetTmpNum(src);
729 dest = (struct Instance *)gl_fetch(dest_list,copynum);
730 switch (copy_lrelns) {
731 case c_reference:
732 lrel = CopyLogRelByReference(src,dest,varlist,rellist);
733 break;
734 case c_tomodify:
735 lrel = CopyLogRelToModify(src,dest,varlist,rellist);
736 break;
737 default:
738 Asc_Panic(2, "CopyLogRelStructures", "Invalid type in CopyLogRelStructures\n"); /* NOTREACHED */
739 lrel = NULL;
740 }
741 SetInstanceLogRel(dest,lrel);
742 gl_reset(varlist);
743 gl_reset(rellist);
744 }
745 gl_destroy(varlist);
746 gl_destroy(rellist);
747 }
748
749
750 static void CopyWhenContents(struct gl_list_t *src_list,
751 struct gl_list_t *dest_list)
752 {
753 CONST struct Instance *src;
754 struct gl_list_t *scratch;
755 unsigned long len,c;
756
757 len = gl_length(src_list);
758 scratch = gl_create(100L);
759
760 for (c=1;c<=len;c++) {
761 src = (CONST struct Instance *)gl_fetch(src_list,c);
762 if (src->t!=WHEN_INST)
763 continue;
764 BuildWhenVarList(src,dest_list,scratch);
765 gl_reset(scratch);
766 BuildWhenCasesList(src,dest_list);
767 }
768 gl_destroy(scratch);
769 }
770
771 static
772 struct Instance *CopyDummy(CONST struct Instance *i)
773 {
774 (void) i; /* intentional */
775 FPRINTF(ASCERR,
776 "CopyDummy called in error -- UNIVERSAL's shouldn't be copied.\n");
777 return NULL;
778 }
779
780 /*
781 *********************************************************************
782 * This copies a node and not it's children unless it is an atom in which
783 * case it copies the whole atom(including its children). This does not
784 * worry about connectivity or anything like that.
785 *********************************************************************
786 */
787 static struct Instance *CopyNode(CONST struct Instance *i)
788 {
789 AssertMemory(i);
790 switch (i->t) {
791 case MODEL_INST:
792 return CopyModel(i);
793 case DUMMY_INST:
794 return CopyDummy(i);
795 case REAL_ATOM_INST:
796 case REAL_CONSTANT_INST:
797 return CopyReal(i);
798 case BOOLEAN_ATOM_INST:
799 case BOOLEAN_CONSTANT_INST:
800 return CopyBoolean(i);
801 case INTEGER_ATOM_INST:
802 case INTEGER_CONSTANT_INST:
803 return CopyInteger(i);
804 case SET_ATOM_INST:
805 return CopySetInst(i);
806 case SYMBOL_ATOM_INST:
807 case SYMBOL_CONSTANT_INST:
808 return CopySymbolInst(i);
809 case REL_INST:
810 return CopyRelationInst(i);
811 case LREL_INST:
812 return CopyLogRelInst(i);
813 case WHEN_INST:
814 return CopyWhenInst(i);
815 case ARRAY_INT_INST:
816 case ARRAY_ENUM_INST:
817 return CopyArray(i);
818 case REAL_INST:
819 case INTEGER_INST:
820 case BOOLEAN_INST:
821 case SET_INST:
822 case SYMBOL_INST:
823 return NULL;
824 default:
825 Asc_Panic(2, NULL, "Incorrect instance type passed to CopyNode.\n");
826 exit(2);/* Needed to keep gcc from whining */
827 }
828 }
829
830 /* this goddamned thing is externed in instanceio rather than being headered */
831 void CollectNodes(struct Instance *i, struct gl_list_t *data)
832 {
833 struct gl_list_t *list;
834 list = data;
835
836 switch (i->t) {
837 case SIM_INST: /* double check this one !! */
838 case MODEL_INST:
839 case REAL_CONSTANT_INST:
840 case INTEGER_CONSTANT_INST:
841 case BOOLEAN_CONSTANT_INST:
842 case SYMBOL_CONSTANT_INST:
843 case REAL_ATOM_INST:
844 case BOOLEAN_ATOM_INST:
845 case INTEGER_ATOM_INST:
846 case SET_ATOM_INST:
847 case SYMBOL_ATOM_INST:
848 case REL_INST:
849 case LREL_INST:
850 case WHEN_INST:
851 case ARRAY_INT_INST:
852 case ARRAY_ENUM_INST:
853 gl_append_ptr(list,(VOIDPTR)i);
854 SetTmpNum(i,gl_length(list));
855 break;
856 case REAL_INST:
857 case INTEGER_INST:
858 case BOOLEAN_INST:
859 case SET_INST:
860 case SYMBOL_INST:
861 break;
862 default:
863 Asc_Panic(2, NULL, "Incorrect instance type passed to CollectNodes.\n");
864 }
865 }
866
867 static unsigned long g_copy_numnodes = 0L;
868
869 static void ResetNodeCount(void)
870 {
871 g_copy_numnodes = 0L;
872 }
873
874 static unsigned long GetNodeCount(void)
875 {
876 return g_copy_numnodes;
877 }
878
879 static void CountNodes(struct Instance *i)
880 {
881 switch (i->t) {
882 case SIM_INST: /* double check this one !! */
883 case MODEL_INST:
884 case REAL_CONSTANT_INST:
885 case INTEGER_CONSTANT_INST:
886 case BOOLEAN_CONSTANT_INST:
887 case SYMBOL_CONSTANT_INST:
888 case REAL_ATOM_INST:
889 case BOOLEAN_ATOM_INST:
890 case INTEGER_ATOM_INST:
891 case SET_ATOM_INST:
892 case SYMBOL_ATOM_INST:
893 case REL_INST:
894 case LREL_INST:
895 case WHEN_INST:
896 case ARRAY_INT_INST:
897 case ARRAY_ENUM_INST:
898 g_copy_numnodes++;
899 break;
900 case REAL_INST:
901 case INTEGER_INST:
902 case BOOLEAN_INST:
903 case SET_INST:
904 case SYMBOL_INST:
905 break;
906 default:
907 Asc_Panic(2, NULL, "Incorrect instance type passed to CountNodes.\n");
908 }
909 }
910
911
912 /*
913 * This function run downs the list of 'copyable' instances,
914 * looking for Universal instances. It then visits the subtree
915 * rooted at the universal instance, resetting the copynums to 0.
916 */
917 static
918 void UnMarkUniversals(struct gl_list_t *list)
919 {
920 unsigned long len,c;
921 struct Instance *ptr;
922 struct TypeDescription *desc;
923
924 len = gl_length(list);
925 for (c=1;c<=len;c++) {
926 ptr = (struct Instance *)gl_fetch(list,c);
927 desc = InstanceTypeDesc(ptr);
928 if (GetUniversalFlag(desc)) {
929 ZeroTmpNums((struct Instance *)ptr,0);
930 }
931 }
932 }
933
934 /*
935 * This function run downs the list of 'copyable' instances,
936 * which has been prepocessed by UnMarkUniversals. If the
937 * copynum of the instance is non-zero, a new node (without any
938 * connectivity) is created and appended to the new list. Otherwise
939 * the instance is simply appended to the new list and its
940 * copynum is reset. NOTE copynum should always be the index
941 * of the instance on the list, except for when we temporarily
942 * unmark them.
943 */
944 static
945 void CopyNodes_ListVersion(struct gl_list_t *original_list,
946 struct gl_list_t *new_list)
947 {
948 unsigned long len,c,copynum;
949 struct Instance *src, *dest;
950
951 len = gl_length(original_list);
952 for (c=1;c<=len;c++) {
953 src = (struct Instance *)gl_fetch(original_list,c);
954 copynum = GetTmpNum(src);
955 if (copynum!=0) {
956 dest = CopyNode(src);
957 gl_append_ptr(new_list,(VOIDPTR)dest);
958 SetTmpNum(dest,c);
959 } else{
960 gl_append_ptr(new_list,(VOIDPTR)src);
961 SetTmpNum(src,c);
962 }
963 }
964 }
965
966 /*
967 * This function does the linking up of the new nodes, and
968 * correctly takes care up of universal instances.
969 * It runs down the old list, and foreach instance, processes its
970 * children. This is done by wiring up the copy and the copy's
971 * children, in the same way that the original is wired up to
972 * its children.
973 * NOTE: If the original and and the copy are looking
974 * at the same instance, then this instance is a universal
975 * instance or is part of the subtree of universal instance and
976 * hence there is nothing to wire up for the copy. Remember that
977 * universals and their subtrees are shared between the original and
978 * any copies.
979 */
980 static
981 void LinkNodes_ListVersion(struct gl_list_t *original_list,
982 struct gl_list_t *new_list)
983 {
984 struct Instance *original, *child;
985 struct Instance *copy, *ptr;
986 struct Instance *next;
987 unsigned long len, c, cc;
988 unsigned long nch, index;
989
990 len = gl_length(original_list);
991 for (c=1;c<=len;c++) {
992 copy = INST(gl_fetch(new_list,c));
993 original = INST(gl_fetch(original_list,c));
994 if (copy==original) {
995 /* universal or its child */
996 continue;
997 }
998 assert(GetTmpNum(original)!=0); /* copynum = 0 is invalid here */
999 nch = NumberChildren(original);
1000 if ( ( InstanceKind(original) &
1001 (ICONS | IATOM | IFUND | IRELN | ILRELN | IWHEN)
1002 ) ==0 /* bit test for no/only fundamental children */
1003 ) {
1004 for (cc=1;cc<=nch;cc++) {
1005 /* only arrays/models should get here */
1006 child = InstanceChild(original,cc);
1007 index = GetTmpNum(child);
1008 assert(index!=0);/* subatomic children dont have copynums */
1009 /* link from child to parent. this could be smarter.
1010 * our handling of UNIVERSAL is poor.
1011 */
1012 ptr = INST(gl_fetch(new_list,index));
1013 if (SearchForParent(ptr,copy)==0) {
1014 AddParent(ptr,copy);
1015 }
1016 /* link from parent to child */
1017 StoreChildPtr(copy,cc,ptr);
1018 }
1019 }
1020
1021 /*
1022 * link ARE_ALIKE cliques. ARE_ALIKE cliques can run a
1023 * thread through instances that are *not* in the subtree
1024 * that is being copied. If the *entire* tree rooted at a
1025 * simulation is properly initialized to 0, then this code
1026 * will correctly link in only those instances in the subtree.
1027 * --kaa
1028 * Note this is a bad assumption -- the universe must have
1029 * tmpnums of 0 when we have the ability to connect parts of
1030 * simulations across objects. This will need revisiting.
1031 * of course with parameterized types, ARE_ALIKE should be
1032 * so much less common that we won't care.
1033 * -baa.
1034 */
1035 ptr = original;
1036 if (NextCliqueMember(ptr)!=ptr) { /* i is in a clique */
1037 do {
1038 ptr = NextCliqueMember(ptr);
1039 index = GetTmpNum(ptr);
1040 if (index) {
1041 next = INST(gl_fetch(new_list,index));
1042 SetNextCliqueMember(copy,next);
1043 copy = next;
1044 }
1045 } while(ptr!=original);
1046 }
1047 }
1048 }
1049
1050
1051 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1052 static
1053 void CheckNewCopy(char *filename, CONST struct Instance *i)
1054 {
1055 FILE *fp;
1056 int opened = 0;
1057
1058 if (strcmp(filename,"ASCERR")==0)
1059 fp = ASCERR;
1060 else if (strcmp(filename,"stdin")==0)
1061 fp = stdin;
1062 else{
1063 fp = fopen(filename,"w");
1064 if (!fp) {
1065 FPRINTF(ASCERR,"Error in opening CheckNewCopy file\n");
1066 return;
1067 }
1068 opened = 1;
1069 }
1070
1071 InstanceStatistics(fp,i);
1072 if (opened) fclose(fp);
1073 }
1074 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1075
1076 /*
1077 * The new instance returned is the last one on the
1078 * list.
1079 */
1080 static
1081 struct Instance *CopyTree(CONST struct Instance *i)
1082 {
1083 struct gl_list_t *orig_list;
1084 struct gl_list_t *new_list;
1085 struct Instance *result = NULL;
1086 unsigned long len;
1087
1088 AssertMemory(i);
1089 ResetNodeCount();
1090 VisitInstanceTree((struct Instance *)i,CountNodes,1,0);
1091 len = GetNodeCount();
1092
1093 new_list = gl_create(len);
1094 orig_list = gl_create(len);
1095
1096 VisitInstanceTreeTwo((struct Instance *)i,(VisitTwoProc)CollectNodes,
1097 1,0,(void *)orig_list);
1098 UnMarkUniversals(orig_list);
1099 CopyNodes_ListVersion(orig_list,new_list);
1100 LinkNodes_ListVersion(orig_list,new_list);
1101 CopyRelationStructures(orig_list,new_list,c_reference);
1102 CopyLogRelStructures(orig_list,new_list,c_reference);
1103 CopyWhenContents(orig_list,new_list);
1104 /*
1105 * reset copy numbers to zero. This is crucial for
1106 * subsequent calls to this function.
1107 */
1108 ZeroTmpNums((struct Instance *)i,1);
1109 ResetNodeCount();
1110
1111 len = gl_length(new_list);
1112 if (len) {
1113 result = INST(gl_fetch(new_list,len));
1114 }
1115 gl_destroy(new_list);
1116 gl_destroy(orig_list);
1117
1118 /* Do some debug checking
1119 CheckNewCopy("new.inst",result);
1120 CheckNewCopy("old.inst",i);
1121 */
1122 return result;
1123 }
1124
1125 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1126 static
1127 struct Instance *DeepCopyTree(CONST struct Instance *i,
1128 enum Copy_enum copy_relns,
1129 enum Copy_enum copy_lrelns)
1130 {
1131 struct gl_list_t *orig_list;
1132 struct gl_list_t *new_list;
1133 struct Instance *result = NULL;
1134 unsigned long len;
1135
1136 AssertMemory(i);
1137 new_list = gl_create(1000L);
1138 orig_list = gl_create(1000L);
1139
1140 VisitInstanceTreeTwo((struct Instance *)i,(VisitTwoProc)CollectNodes,
1141 1,0,(void *)orig_list);
1142 UnMarkUniversals(orig_list);
1143 CopyNodes_ListVersion(orig_list,new_list);
1144 LinkNodes_ListVersion(orig_list,new_list);
1145 if (copy_relns!=c_none)
1146 CopyRelationStructures(orig_list,new_list,copy_relns);
1147 if (copy_lrelns!=c_none)
1148 CopyLogRelStructures(orig_list,new_list,copy_lrelns);
1149 CopyWhenContents(orig_list,new_list);
1150 /*
1151 * reset copy numbers to zero. This is crucial for
1152 * subsequent calls to this function.
1153 */
1154 ZeroTmpNums((struct Instance *)i,1);
1155
1156 len = gl_length(new_list);
1157 if (len) {
1158 result = INST(gl_fetch(new_list,len));
1159 }
1160 gl_destroy(new_list);
1161 gl_destroy(orig_list);
1162
1163 return result;
1164 }
1165 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1166
1167
1168 struct Instance *CopyInstance(CONST struct Instance *i)
1169 {
1170 AssertMemory(i);
1171 switch(i->t) {
1172 case SIM_INST:
1173 /* We are being strict and copying the SIM_INST */
1174 return CopyTree(i);
1175 case MODEL_INST:
1176 return CopyTree(i);
1177 case REAL_ATOM_INST:
1178 case REAL_CONSTANT_INST:
1179 return CopyReal(i);
1180 case BOOLEAN_ATOM_INST:
1181 case BOOLEAN_CONSTANT_INST:
1182 return CopyBoolean(i);
1183 case INTEGER_ATOM_INST:
1184 case INTEGER_CONSTANT_INST:
1185 return CopyInteger(i);
1186 case SET_ATOM_INST:
1187 return CopySetInst(i);
1188 case SYMBOL_ATOM_INST:
1189 case SYMBOL_CONSTANT_INST:
1190 return CopySymbolInst(i);
1191 case REL_INST:
1192 return CopyRelationInst(i);
1193 case LREL_INST:
1194 return CopyLogRelInst(i);
1195 case WHEN_INST:
1196 return CopyWhenInst(i);
1197 case ARRAY_INT_INST:
1198 case ARRAY_ENUM_INST:
1199 return CopyTree(i);
1200 case REAL_INST:
1201 case INTEGER_INST:
1202 case BOOLEAN_INST:
1203 case SET_INST:
1204 case SYMBOL_INST:
1205 Asc_Panic(2, NULL,
1206 "CopyInstance may not be called on"
1207 " fundamental atomic instances.\n");
1208 exit(2);/* Needed to keep gcc from whining */
1209 default:
1210 Asc_Panic(2, NULL, "Unknown instance type passed to CopyInstance.\n");
1211 exit(2);/* Needed to keep gcc from whining */
1212 }
1213 }
1214 /************ end of copy stuff ****************/
1215

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