source: git/MP/MPT/MPT_Tree.cc @ 4d9c27

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