void tnode_free(tnode *T) { REQUIRES(is_tnode_root(T)); if (T == NULL) return; tnode_free(T->left); tnode_free(T->middle); tnode_free(T->right); free(T); }
/* * called to simplify a traces-language expression (postwalk order) * returns 0 to stop walk, 1 to continue */ static int traceslang_simplifyexpr_modpostwalk (tnode_t **nodep, void *arg) { tnode_t *n = *nodep; if ((n->tag == traceslang.tag_SEQ) || (n->tag == traceslang.tag_PAR) || (n->tag == traceslang.tag_DET) || (n->tag == traceslang.tag_NDET)) { /*{{{ SEQ,PAR,DET,NDET -- collapse singles, merge nested*/ int nitems, i; tnode_t *ilist = tnode_nthsubof (n, 0); tnode_t **items; parser_cleanuplist (ilist); items = parser_getlistitems (ilist, &nitems); if (nitems == 1) { /* single item! */ tnode_t *tmp = items[0]; items[0] = NULL; tnode_free (n); *nodep = tmp; } else { /* otherwise, see if we can merge nested trees */ for (i=0; i<nitems; i++) { if (items[i]->tag == n->tag) { /* collapse this one */ int nsubitems, j; tnode_t *sublist = tnode_nthsubof (items[i], 0); tnode_t **subitems = parser_getlistitems (sublist, &nsubitems); /* replacing item 'i' to start with */ parser_delfromlist (ilist, i); for (j=0; j<nsubitems; j++, i++) { parser_insertinlist (ilist, subitems[j], i); subitems[j] = NULL; } i--; /* reset items incase it moved! */ items = parser_getlistitems (ilist, &nitems); } } } /*}}}*/ } else if ((n->tag == traceslang.tag_INPUT) || (n->tag == traceslang.tag_OUTPUT)) { /*{{{ INPUT,OUTPUT -- remove if NULL body*/ tnode_t *item = tnode_nthsubof (n, 0); if (!item) { *nodep = NULL; tnode_free (n); } /*}}}*/ } return 1; }
/* * turns a simple list of traces into a non-deterministic choice of them * returns new tree on success, NULL on failure */ tnode_t *traceslang_listtondet (tnode_t *expr) { int nitems; tnode_t **items; if (!expr) { nocc_serious ("traceslang_listtondet(): NULL expression!"); return NULL; } if (!parser_islistnode (expr)) { nocc_serious ("traceslang_listtondet(): expression is not a list! (%s,%s)", expr->tag->name, expr->tag->ndef->name); return expr; } items = parser_getlistitems (expr, &nitems); if (nitems == 1) { /* collapse single item */ tnode_t *tmp = items[0]; items[0] = NULL; tnode_free (expr); return tmp; } else if (nitems > 1) { /* make a non-deterministic choice */ return tnode_createfrom (traceslang.tag_NDET, expr, expr); } return expr; }
/* * this goes through a trace and removes trailing "Skip"s, or turns trailing ends into fixpoint loops * returns 0 on success, non-zero on failure */ int traceslang_noskiporloop (tnode_t **exprp) { traceslang_erefset_t *tailrefs = traceslang_lastactionsp (exprp); tnode_t *fixname; int i, fixcount = 0; fixname = tnode_create (traceslang.tag_NFIX, NULL, NULL); #if 0 fprintf (stderr, "traceslang_noskiporloop(): transforming:\n"); tnode_dumptree (*exprp, 1, stderr); fprintf (stderr, "traceslang_noskiporloop(): with tail references:\n"); traceslang_dumprefset (tailrefs, 1, stderr); #endif for (i=0; i<DA_CUR (tailrefs->events); i++) { tnode_t **eventp = DA_NTHITEM (tailrefs->events, i); tnode_t *ev = *eventp; if (ev->tag == traceslang.tag_SKIP) { /* remove from traces */ *eventp = NULL; tnode_free (ev); } else if (ev->tag == traceslang.tag_NPARAM) { /* trailing event, sequential with fixpoint instance */ tnode_t *ilist = parser_buildlistnode (NULL, ev, fixname, NULL); *eventp = tnode_createfrom (traceslang.tag_SEQ, ev, ilist); fixcount++; } } if (fixcount) { char *rfixname = (char *)smalloc (64); name_t *sfixname; tnode_t *fixnode; sprintf (rfixname, "FP%d", anonidcounter++); sfixname = name_addname (rfixname, NULL, tnode_create (traceslang.tag_FIXPOINTTYPE, NULL), fixname); sfree (rfixname); tnode_setnthname (fixname, 0, sfixname); fixnode = tnode_createfrom (traceslang.tag_FIXPOINT, *exprp, fixname, *exprp); SetNameDecl (sfixname, fixnode); *exprp = fixnode; } traceslang_freerefset (tailrefs); #if 0 fprintf (stderr, "traceslang_noskiporloop(): into:\n"); tnode_dumptree (*exprp, 1, stderr); #endif return 0; }
/* * frees a consthook_t structure */ static void cprop_consthook_hook_free (void *hook) { consthook_t *ch = (consthook_t *)hook; if (!ch) { return; } if (ch->orig) { tnode_free (ch->orig); } sfree (ch); return; }
void trie_free(trie TR) { REQUIRES(is_trie(TR)); tnode_free(TR->root); free(TR); }