1 | /****************************************************************** |
---|
2 | * |
---|
3 | * File: MPT_Tree.c |
---|
4 | * Purpose: Copying/Deleting MPT Trees |
---|
5 | * Author: Olaf Bachman (obachman@mathematik.uni-kl.de) |
---|
6 | * Created: 12/96 |
---|
7 | * |
---|
8 | * Change History (most recent first): |
---|
9 | * |
---|
10 | ******************************************************************/ |
---|
11 | #include "MPT.h" |
---|
12 | #include <string.h> |
---|
13 | |
---|
14 | #ifndef __64_BIT__ |
---|
15 | #define MPT_Delete64BitType(arg) IMP_MemFreeFnc(arg, sizeof(MP_Real64_t)) |
---|
16 | static void MPT_Cpy64BitType(MPT_Arg_t *odest, MPT_Arg_t src) |
---|
17 | { |
---|
18 | MP_Real64_t *r64_pt = (MP_Real64_t *) IMP_MemAllocFnc(sizeof(MP_Real64_t)); |
---|
19 | *r64_pt = MP_REAL64_T(src); |
---|
20 | *odest = r64_pt; |
---|
21 | } |
---|
22 | #else |
---|
23 | #define MPT_Delete64BitType(arg) ((void *) 0) |
---|
24 | #define MPT_Cpy64BitType(dest, src) *(dest) = src |
---|
25 | #endif |
---|
26 | |
---|
27 | /******************************************************************* |
---|
28 | * |
---|
29 | * Deleting a tree |
---|
30 | * |
---|
31 | *******************************************************************/ |
---|
32 | |
---|
33 | void MPT_DeleteTree(MPT_Tree_pt tree) |
---|
34 | { |
---|
35 | if (tree != NULL) |
---|
36 | { |
---|
37 | MPT_Assume(tree->node != NULL); |
---|
38 | |
---|
39 | /* Delete the args, if there are any */ |
---|
40 | if (tree->node->type == MP_CommonOperatorType || |
---|
41 | tree->node->type == MP_OperatorType) |
---|
42 | MPT_DeleteArgs(tree->args, tree->node->numchild, |
---|
43 | MPT_ProtoAnnotValue(tree->node)); |
---|
44 | /* Check for external data */ |
---|
45 | else if (tree->node->type == MPT_ExternalDataType) |
---|
46 | MPT_DeleteExternalData(tree->args); |
---|
47 | /* else, it is a node which has no arguments */ |
---|
48 | |
---|
49 | MPT_DeleteNode(tree->node); |
---|
50 | |
---|
51 | IMP_MemFreeFnc(tree, sizeof(MPT_Tree_t)); |
---|
52 | } |
---|
53 | } |
---|
54 | |
---|
55 | |
---|
56 | void MPT_DeleteNode(MPT_Node_pt node) |
---|
57 | { |
---|
58 | MP_NumAnnot_t numannot = node->numannot; |
---|
59 | MP_NodeType_t type = node->type; |
---|
60 | /* take care of annots, if there are any */ |
---|
61 | if (numannot > 0) |
---|
62 | { |
---|
63 | MP_Uint32_t i; |
---|
64 | MPT_Annot_pt *annots = node->annots, annot; |
---|
65 | |
---|
66 | MPT_Assume(annots != NULL); |
---|
67 | |
---|
68 | for (i=0; i<numannot; i++) |
---|
69 | { |
---|
70 | annot = annots[i]; |
---|
71 | MPT_Assume(annot != NULL); |
---|
72 | if (MP_IsAnnotValuated(annot->flags)) |
---|
73 | MPT_DeleteTree(annot->value); |
---|
74 | IMP_MemFreeFnc(annot, sizeof(MPT_Annot_t)); |
---|
75 | } |
---|
76 | |
---|
77 | IMP_MemFreeFnc(node->annots, numannot*sizeof(MPT_Annot_pt)); |
---|
78 | } |
---|
79 | |
---|
80 | /* delet nvalue, if necessary */ |
---|
81 | if (node->nvalue != NULL) |
---|
82 | { |
---|
83 | if (MP_IsStringBasedType(type) || |
---|
84 | type == MP_OperatorType || |
---|
85 | type == MP_MetaOperatorType) |
---|
86 | IMP_RawMemFreeFnc(node->nvalue); |
---|
87 | else if (type == MP_ApIntType) |
---|
88 | MPT_DeleteApInt(node->nvalue); |
---|
89 | else if (type == MP_ApRealType) |
---|
90 | MPT_DeleteApReal(node->nvalue); |
---|
91 | else if (MP_Is64BitNumericType(type)) |
---|
92 | MPT_Delete64BitType(node->nvalue); |
---|
93 | } |
---|
94 | |
---|
95 | IMP_MemFreeFnc(node, sizeof(MPT_Node_t)); |
---|
96 | } |
---|
97 | |
---|
98 | void MPT_DeleteArgs(MPT_Arg_pt args, MP_NumChild_t nc, |
---|
99 | MPT_Tree_pt typespec) |
---|
100 | { |
---|
101 | MP_NumChild_t i; |
---|
102 | MP_Uint32_t size = 0; |
---|
103 | |
---|
104 | /* return, if args == NULL, i.e. node is a leave node of a tree */ |
---|
105 | if (args == NULL || nc == 0) return; |
---|
106 | |
---|
107 | /* Check for non-prototyped data */ |
---|
108 | if (typespec == NULL) |
---|
109 | { |
---|
110 | for (i=0; i<nc; i++) |
---|
111 | MPT_DeleteTree(MPT_TREE_PT(args[i])); |
---|
112 | size = nc*sizeof(MPT_Arg_t); |
---|
113 | } |
---|
114 | else |
---|
115 | { |
---|
116 | /* Now we are in the realm of prototyped data */ |
---|
117 | MPT_Node_pt pnode = typespec->node; |
---|
118 | MP_NodeType_t ptype = pnode->type; |
---|
119 | MP_DictTag_t pdict = pnode->dict; |
---|
120 | |
---|
121 | /* Check only for arrays of basic numeric types */ |
---|
122 | if (ptype == MP_CommonMetaType && pdict == MP_ProtoDict) |
---|
123 | { |
---|
124 | MP_Common_t metatype = MP_COMMON_T(pnode->nvalue); |
---|
125 | |
---|
126 | if (IMP_Is8BitNumericMetaType(metatype)) |
---|
127 | size = nc*sizeof(MP_Uint8_t); |
---|
128 | else if (IMP_Is32BitNumericMetaType(metatype)) |
---|
129 | size = nc*sizeof(MP_Uint32_t); |
---|
130 | else if (IMP_Is64BitNumericMetaType(metatype)) |
---|
131 | size = nc*sizeof(MP_Real64_t); |
---|
132 | } |
---|
133 | |
---|
134 | /* Everything else is handled item by item */ |
---|
135 | if (size == 0) |
---|
136 | { |
---|
137 | for (i=0;i<nc; i++) |
---|
138 | MPT_DeleteTypespecedArg(args[i], typespec); |
---|
139 | size = nc*sizeof(MPT_Arg_t); |
---|
140 | } |
---|
141 | } |
---|
142 | |
---|
143 | /* Delete Args */ |
---|
144 | IMP_MemFreeFnc(args, size); |
---|
145 | } |
---|
146 | |
---|
147 | |
---|
148 | void MPT_DeleteTypespecedArg(MPT_Arg_t arg, MPT_Tree_pt typespec) |
---|
149 | { |
---|
150 | /* check for trivial cases */ |
---|
151 | if (arg == NULL) return; |
---|
152 | |
---|
153 | if (typespec != NULL) |
---|
154 | { |
---|
155 | MPT_Node_pt typespec_node = typespec->node; |
---|
156 | MPT_Arg_pt typespec_args = typespec->args; |
---|
157 | MP_DictTag_t ndict = typespec_node->dict; |
---|
158 | MP_NodeType_t ntype = typespec_node->type; |
---|
159 | MP_NumChild_t nc = typespec_node->numchild; |
---|
160 | MP_Common_t cvalue = MP_COMMON_T(typespec_node->nvalue); |
---|
161 | |
---|
162 | /* check special Common Meta types from ProtoDict */ |
---|
163 | if (ndict == MP_ProtoDict && ntype == MP_CommonMetaType) |
---|
164 | { |
---|
165 | /* do nothing for types with sizeof <= sizeof(MPT_Arg_t) */ |
---|
166 | if (IMP_Is32BitNumericMetaType(cvalue) || |
---|
167 | IMP_Is8BitNumericMetaType(cvalue)) |
---|
168 | return; |
---|
169 | |
---|
170 | if (cvalue == MP_CmtProtoIMP_ApInt) |
---|
171 | { |
---|
172 | MPT_DeleteApInt(arg); |
---|
173 | return; |
---|
174 | } |
---|
175 | else if (cvalue == MP_CmtProtoIMP_ApReal) |
---|
176 | { |
---|
177 | MPT_DeleteApReal(arg); |
---|
178 | return; |
---|
179 | } |
---|
180 | else if (IMP_Is64BitNumericMetaType(cvalue)) |
---|
181 | { |
---|
182 | MPT_Delete64BitType(arg); |
---|
183 | return; |
---|
184 | } |
---|
185 | else if (IMP_IsStringBasedMetaType(cvalue)) |
---|
186 | { |
---|
187 | IMP_RawMemFreeFnc(arg); |
---|
188 | return; |
---|
189 | } |
---|
190 | else if (cvalue == MP_CmtProtoRecStruct) |
---|
191 | { |
---|
192 | MPT_DeleteTypespecedArg(arg, MPT_RecStructTree); |
---|
193 | return; |
---|
194 | } |
---|
195 | else if (cvalue == MP_CmtProtoRecUnion) |
---|
196 | { |
---|
197 | MPT_DeleteTypespecedArg(arg, MPT_RecUnionTree); |
---|
198 | return; |
---|
199 | } |
---|
200 | } |
---|
201 | |
---|
202 | /* special MP Operators */ |
---|
203 | if (ntype == MP_CommonOperatorType && ndict == MP_ProtoDict) |
---|
204 | { |
---|
205 | /* ProtoD:Union */ |
---|
206 | if (cvalue == MP_CopProtoUnion || cvalue == MP_CopProtoRecUnion) |
---|
207 | { |
---|
208 | MPT_Union_pt mun = MPT_UNION_PT(arg); |
---|
209 | MPT_Assume(mun->tag <= nc); |
---|
210 | if (mun->tag > 0) |
---|
211 | MPT_DeleteTypespecedArg(mun->arg, |
---|
212 | MPT_TREE_PT(typespec_args[mun->tag -1])); |
---|
213 | IMP_MemFreeFnc(mun, sizeof(MPT_Union_t)); |
---|
214 | return; |
---|
215 | } |
---|
216 | |
---|
217 | /* ProtoD:Struct */ |
---|
218 | if (cvalue == MP_CopProtoStruct || cvalue == MP_CopProtoRecStruct) |
---|
219 | { |
---|
220 | MP_NumChild_t i; |
---|
221 | MPT_Arg_pt st_args = MPT_ARG_PT(arg); |
---|
222 | for (i=0; i<nc; i++) |
---|
223 | MPT_DeleteTypespecedArg(st_args[i], MPT_TREE_PT(typespec_args[i])); |
---|
224 | IMP_MemFreeFnc(arg, nc*sizeof(MPT_Arg_t)); |
---|
225 | return; |
---|
226 | } |
---|
227 | } |
---|
228 | |
---|
229 | /* Meta Operators */ |
---|
230 | if (ntype == MP_CommonMetaOperatorType || ntype == MP_MetaOperatorType) |
---|
231 | { |
---|
232 | MPT_DynArgs_pt dynargs = NULL; |
---|
233 | MPT_Arg_pt args; |
---|
234 | typespec = MPT_ProtoAnnotValue(typespec_node); |
---|
235 | |
---|
236 | if (nc == 0) |
---|
237 | { |
---|
238 | dynargs = MPT_DYNARGS_PT(arg); |
---|
239 | nc = dynargs->length; |
---|
240 | args = dynargs->args; |
---|
241 | } |
---|
242 | else |
---|
243 | args = MPT_ARG_PT(arg); |
---|
244 | |
---|
245 | MPT_DeleteArgs(args, nc, typespec); |
---|
246 | if (dynargs != NULL) |
---|
247 | IMP_MemFreeFnc(dynargs, sizeof(MPT_DynArgs_t)); |
---|
248 | return; |
---|
249 | } |
---|
250 | } |
---|
251 | |
---|
252 | /* Everything else is taken to be a tree */ |
---|
253 | MPT_DeleteTree(MPT_TREE_PT(arg)); |
---|
254 | } |
---|
255 | |
---|
256 | /******************************************************************* |
---|
257 | * |
---|
258 | * Copying a tree |
---|
259 | * |
---|
260 | *******************************************************************/ |
---|
261 | |
---|
262 | void MPT_CpyTree(MPT_Tree_pt *otree, MPT_Tree_pt src) |
---|
263 | { |
---|
264 | if (src == NULL) |
---|
265 | *otree = NULL; |
---|
266 | else |
---|
267 | { |
---|
268 | MPT_Tree_pt dest = (MPT_Tree_pt) IMP_MemAllocFnc(sizeof(MPT_Tree_t)); |
---|
269 | MPT_Node_pt snode = src->node; |
---|
270 | MP_NodeType_t stype = snode->type; |
---|
271 | |
---|
272 | *otree = dest; |
---|
273 | MPT_CpyNode(&(dest->node), src->node); |
---|
274 | |
---|
275 | /* Copy Args, if necessary */ |
---|
276 | if (stype == MP_CommonOperatorType || stype == MP_OperatorType) |
---|
277 | { |
---|
278 | MP_Common_t nvalue = MP_COMMON_T(snode->nvalue); |
---|
279 | MP_DictTag_t ndict = snode->dict; |
---|
280 | |
---|
281 | /* we might have to push the current tree onto the stack of |
---|
282 | recursive typespecs */ |
---|
283 | if (ndict == MP_ProtoDict) |
---|
284 | { |
---|
285 | if (nvalue == MP_CopProtoRecUnion) |
---|
286 | MPT_PushRecUnion(dest); |
---|
287 | else if (nvalue == MP_CopProtoRecStruct) |
---|
288 | MPT_PushRecStruct(dest); |
---|
289 | } |
---|
290 | |
---|
291 | /* Copy Args */ |
---|
292 | MPT_CpyArgs(&(dest->args), src->args, |
---|
293 | snode->numchild, MPT_ProtoAnnotValue(snode)); |
---|
294 | |
---|
295 | /* And, pop the recursive typesepcs again */ |
---|
296 | if (ndict == MP_ProtoDict) |
---|
297 | { |
---|
298 | if (nvalue == MP_CopProtoRecUnion) |
---|
299 | MPT_PopRecUnion(); |
---|
300 | else if (nvalue == MP_CopProtoRecStruct) |
---|
301 | MPT_PopRecStruct(); |
---|
302 | } |
---|
303 | } |
---|
304 | /* No args */ |
---|
305 | else if (stype == MPT_ExternalDataType) |
---|
306 | MPT_CpyExternalData(MPT_ARG_PT(&(dest->args)), src->args); |
---|
307 | else |
---|
308 | dest->args = NULL; |
---|
309 | } |
---|
310 | } |
---|
311 | |
---|
312 | void MPT_CpyNode(MPT_Node_pt *onode, MPT_Node_pt node) |
---|
313 | { |
---|
314 | MPT_Node_pt dest = (MPT_Node_pt) IMP_MemAllocFnc(sizeof(MPT_Node_t)); |
---|
315 | MP_NumAnnot_t numannot = node->numannot; |
---|
316 | MP_NodeType_t type = node->type; |
---|
317 | |
---|
318 | *onode = dest; |
---|
319 | memcpy(dest, node, sizeof(MPT_Node_t)); |
---|
320 | |
---|
321 | /* take care of annots, if there are any */ |
---|
322 | if (numannot > 0) |
---|
323 | { |
---|
324 | MP_Uint32_t i; |
---|
325 | MPT_Annot_pt annot, dannot, |
---|
326 | *annots = node->annots, |
---|
327 | *dannots = (MPT_Annot_pt*)IMP_MemAllocFnc(numannot*sizeof(MPT_Annot_pt)); |
---|
328 | dest->annots = dannots; |
---|
329 | |
---|
330 | for (i=0; i<numannot; i++) |
---|
331 | { |
---|
332 | annot = annots[i]; |
---|
333 | MPT_Assume(annot != NULL); |
---|
334 | |
---|
335 | dannot = (MPT_Annot_pt) IMP_MemAllocFnc(sizeof(MPT_Annot_t)); |
---|
336 | dannots[i] = dannot; |
---|
337 | |
---|
338 | memcpy(dannot, annot, sizeof(MPT_Annot_t)); |
---|
339 | if (MP_IsAnnotValuated(annot->flags)) |
---|
340 | MPT_CpyTree(&(dannot->value), annot->value); |
---|
341 | } |
---|
342 | } |
---|
343 | |
---|
344 | /* cpy nvalue, if necessary */ |
---|
345 | if (MP_IsStringBasedType(type) || |
---|
346 | type == MP_OperatorType || |
---|
347 | type == MP_MetaOperatorType) |
---|
348 | { |
---|
349 | dest->nvalue |
---|
350 | = IMP_RawMemAllocFnc( |
---|
351 | (strlen(MP_STRING_T(node->nvalue))+1)*sizeof(char)); |
---|
352 | strcpy((char*) dest->nvalue, (char*) node->nvalue); |
---|
353 | } |
---|
354 | else if (type == MP_ApIntType) |
---|
355 | MPT_InitCopyApInt(&(dest->nvalue), node->nvalue); |
---|
356 | else if (type == MP_ApRealType) |
---|
357 | MPT_InitCopyApReal(&(dest->nvalue), node->nvalue); |
---|
358 | else if (type == MP_Real64Type) |
---|
359 | MPT_Cpy64BitType(&(dest->nvalue), node->nvalue); |
---|
360 | } |
---|
361 | |
---|
362 | void MPT_CpyArgs(MPT_Arg_pt *oargs, MPT_Arg_pt args, |
---|
363 | MP_NumChild_t nc, MPT_Tree_pt typespec) |
---|
364 | { |
---|
365 | /* return, if args == NULL, i.e. node is a leave node of a tree */ |
---|
366 | if (args == NULL || nc == 0) |
---|
367 | *oargs = NULL; |
---|
368 | else |
---|
369 | { |
---|
370 | MP_NumChild_t i; |
---|
371 | MPT_Arg_pt dargs; |
---|
372 | |
---|
373 | /* Check for non-prototyped data */ |
---|
374 | if (typespec == NULL) |
---|
375 | { |
---|
376 | dargs = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t)); |
---|
377 | *oargs = dargs; |
---|
378 | |
---|
379 | for (i=0; i<nc; i++) |
---|
380 | MPT_CpyTree((MPT_Tree_pt *) &(dargs[i]), MPT_TREE_PT(args[i])); |
---|
381 | } |
---|
382 | else |
---|
383 | { |
---|
384 | /* Now we are in the realm of prototyped data */ |
---|
385 | MPT_Node_pt pnode = typespec->node; |
---|
386 | MP_NodeType_t ptype = pnode->type; |
---|
387 | MP_DictTag_t pdict = pnode->dict; |
---|
388 | MP_Uint32_t size = 0; |
---|
389 | |
---|
390 | /* Check only for arrays of basic numeric types */ |
---|
391 | if (ptype == MP_CommonMetaType && pdict == MP_ProtoDict) |
---|
392 | { |
---|
393 | MP_Common_t metatype = MP_COMMON_T(pnode->nvalue); |
---|
394 | |
---|
395 | if (IMP_Is8BitNumericMetaType(metatype)) |
---|
396 | size = nc*sizeof(MP_Uint8_t); |
---|
397 | else if (IMP_Is32BitNumericMetaType(metatype)) |
---|
398 | size = nc*sizeof(MP_Uint32_t); |
---|
399 | else if (IMP_Is64BitNumericMetaType(metatype)) |
---|
400 | size = nc*sizeof(MP_Real64_t); |
---|
401 | } |
---|
402 | |
---|
403 | /* Everything else is handled item by item */ |
---|
404 | if (size == 0) |
---|
405 | { |
---|
406 | dargs = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t)); |
---|
407 | *oargs = dargs; |
---|
408 | |
---|
409 | for (i=0;i<nc; i++) |
---|
410 | MPT_CpyTypespecedArg(&(dargs[i]), args[i], typespec); |
---|
411 | } |
---|
412 | else |
---|
413 | { |
---|
414 | dargs = (MPT_Arg_pt) IMP_MemAllocFnc(size); |
---|
415 | *oargs = dargs; |
---|
416 | memcpy(dargs, args, size); |
---|
417 | } |
---|
418 | } |
---|
419 | } |
---|
420 | } |
---|
421 | |
---|
422 | |
---|
423 | |
---|
424 | void MPT_CpyTypespecedArg(MPT_Arg_t *oarg, |
---|
425 | MPT_Arg_t arg, MPT_Tree_pt typespec) |
---|
426 | { |
---|
427 | /* check for trivial cases */ |
---|
428 | if (arg == NULL) |
---|
429 | { |
---|
430 | *oarg = NULL; |
---|
431 | return; |
---|
432 | } |
---|
433 | |
---|
434 | if (typespec != NULL) |
---|
435 | { |
---|
436 | /* Non-trivial cases of typespeced data */ |
---|
437 | MPT_Node_pt typespec_node = typespec->node; |
---|
438 | MPT_Arg_pt typespec_args = typespec->args; |
---|
439 | MP_DictTag_t ndict = typespec_node->dict; |
---|
440 | MP_NodeType_t ntype = typespec_node->type; |
---|
441 | MP_NumChild_t nc = typespec_node->numchild; |
---|
442 | MP_Common_t cvalue = MP_COMMON_T(typespec_node->nvalue); |
---|
443 | |
---|
444 | *oarg = arg; |
---|
445 | /* check special Common Meta types from ProtoDict */ |
---|
446 | if (ndict == MP_ProtoDict && ntype == MP_CommonMetaType) |
---|
447 | { |
---|
448 | /* do nothing for types with sizeof <= sizeof(MPT_Arg_t) */ |
---|
449 | if (IMP_Is32BitNumericMetaType(cvalue) || |
---|
450 | IMP_Is8BitNumericMetaType(cvalue)) |
---|
451 | return; |
---|
452 | |
---|
453 | if (cvalue == MP_CmtProtoIMP_ApInt) |
---|
454 | { |
---|
455 | MPT_InitCopyApInt(oarg, arg); |
---|
456 | return; |
---|
457 | } |
---|
458 | else if (cvalue == MP_CmtProtoIMP_ApReal) |
---|
459 | { |
---|
460 | MPT_InitCopyApReal(oarg, arg); |
---|
461 | return; |
---|
462 | } |
---|
463 | else if (IMP_Is64BitNumericMetaType(cvalue)) |
---|
464 | { |
---|
465 | MPT_Cpy64BitType(oarg, arg); |
---|
466 | return; |
---|
467 | } |
---|
468 | else if (IMP_IsStringBasedMetaType(cvalue)) |
---|
469 | { |
---|
470 | *oarg = IMP_RawMemAllocFnc((strlen(MP_STRING_T(arg))+1)*sizeof(char)); |
---|
471 | strcpy(MP_STRING_T(*oarg), MP_STRING_T(arg)); |
---|
472 | return; |
---|
473 | } |
---|
474 | else if (cvalue == MP_CmtProtoRecStruct) |
---|
475 | { |
---|
476 | MPT_CpyTypespecedArg(oarg, arg, MPT_RecStructTree); |
---|
477 | return; |
---|
478 | } |
---|
479 | else if (cvalue == MP_CmtProtoRecUnion) |
---|
480 | { |
---|
481 | MPT_CpyTypespecedArg(oarg, arg, MPT_RecUnionTree); |
---|
482 | return; |
---|
483 | } |
---|
484 | } |
---|
485 | |
---|
486 | /* special MP Operators */ |
---|
487 | if (ntype == MP_CommonOperatorType && ndict == MP_ProtoDict) |
---|
488 | { |
---|
489 | /* ProtoD:Union */ |
---|
490 | if (cvalue == MP_CopProtoUnion || cvalue == MP_CopProtoRecUnion) |
---|
491 | { |
---|
492 | MPT_Union_pt mun = MPT_UNION_PT(arg), |
---|
493 | dun = (MPT_Union_pt) IMP_MemAllocFnc(sizeof(MPT_Union_t)); |
---|
494 | |
---|
495 | MPT_Assume(mun->tag <= nc); |
---|
496 | dun->tag = mun->tag; |
---|
497 | *oarg = (MPT_Arg_t) dun; |
---|
498 | if (mun->tag > 0) |
---|
499 | MPT_CpyTypespecedArg(&(dun->arg), mun->arg, |
---|
500 | MPT_TREE_PT(typespec_args[mun->tag-1])); |
---|
501 | else |
---|
502 | dun->arg = NULL; |
---|
503 | return; |
---|
504 | } |
---|
505 | |
---|
506 | /* ProtoD:Struct */ |
---|
507 | if (cvalue == MP_CopProtoStruct || cvalue == MP_CopProtoRecStruct) |
---|
508 | { |
---|
509 | MPT_Arg_pt st_args = MPT_ARG_PT(arg), |
---|
510 | dst_args = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t)); |
---|
511 | MP_NumChild_t i; |
---|
512 | |
---|
513 | *oarg = dst_args; |
---|
514 | for (i=0; i<nc; i++) |
---|
515 | MPT_CpyTypespecedArg(&(dst_args[i]), st_args[i], |
---|
516 | MPT_TREE_PT(typespec_args[i])); |
---|
517 | return; |
---|
518 | } |
---|
519 | } |
---|
520 | |
---|
521 | /* Meta Operators */ |
---|
522 | if (ntype == MP_CommonMetaOperatorType || ntype == MP_MetaOperatorType) |
---|
523 | { |
---|
524 | MPT_Arg_pt args, *dargs; |
---|
525 | typespec = MPT_ProtoAnnotValue(typespec_node); |
---|
526 | |
---|
527 | if (nc == 0) |
---|
528 | { |
---|
529 | MPT_DynArgs_pt dynargs = MPT_DYNARGS_PT(arg), ddynargs; |
---|
530 | |
---|
531 | nc = dynargs->length; |
---|
532 | ddynargs = (MPT_DynArgs_pt) IMP_MemAllocFnc(sizeof(MPT_DynArgs_t)); |
---|
533 | *oarg = ddynargs; |
---|
534 | ddynargs->length = nc; |
---|
535 | |
---|
536 | args = dynargs->args; |
---|
537 | dargs = &(ddynargs->args); |
---|
538 | } |
---|
539 | else |
---|
540 | { |
---|
541 | args = MPT_ARG_PT(arg); |
---|
542 | dargs = (MPT_Arg_pt *) oarg; |
---|
543 | } |
---|
544 | |
---|
545 | MPT_CpyArgs(dargs, args, nc, typespec); |
---|
546 | return; |
---|
547 | } |
---|
548 | } |
---|
549 | |
---|
550 | /* Everything else is taken to be a tree */ |
---|
551 | MPT_CpyTree((MPT_Tree_pt *) oarg, MPT_TREE_PT(arg)); |
---|
552 | } |
---|
553 | |
---|