Exemplo n.º 1
0
/*****************************************************************************
 *
 *  casesin takes a list of selections 'tptr' and returns the number of
 *          distinct selections (including an ELSE if one present).
 *
 *****************************************************************************/
PRIVATE int casesin (treenode * tptr)
{
	int n = 0;
	for (; !EndOfList (tptr); tptr = NextItem (tptr)) {
		treenode *thisguard = CondGuardOf (skipspecifications (ThisItem (tptr)));
		if (TagOf (thisguard) == S_ELSE)
			n++;
		else
			n += listitems (thisguard);
	}
	return (n);
}
Exemplo n.º 2
0
Item *ConcatLists(Item *list1, Item *list2)
/* Notes: * Refrain from freeing list2 after using ConcatLists
          * list1 must have at least one element in it */
{
    if (list1 == NULL)
    {
        ProgrammingError("ConcatLists: first argument must have at least one element");
    }
    Item *tail = EndOfList(list1);
    assert(tail != CF_UNDEFINED_ITEM);
    assert(tail->next == NULL);
    /* If any entry in list1 is in list2, so is tail; so this is a
     * sufficient check that we're not creating a loop: */
    assert(!ItemIsInList(list2, tail));
    tail->next = list2;
    return list1;
}
Exemplo n.º 3
0
void AppendItem(Item **liststart, const char *itemstring, const char *classes)
{
    Item *ip = xcalloc(1, sizeof(Item));

    ip->name = xstrdup(itemstring);
    if (classes)
    {
        ip->classes = xstrdup(classes); /* unused now */
    }

    if (*liststart == NULL)
    {
        *liststart = ip;
    }
    else
    {
        Item *lp = EndOfList(*liststart);
        assert(lp != CF_UNDEFINED_ITEM);
        lp->next = ip;
    }
}
Exemplo n.º 4
0
/*****************************************************************************
 *
 *  tcase generates code for a case process tptr
 *
 *****************************************************************************/
PUBLIC void tcase (treenode * tptr)
{
	/*{{{  save globals */
	caseentry *const oldcasetable = casetable;
	const int olddefaultlab = defaultlab;
	const int olddefaultjumpdest = defaultjumpdest;
	const int oldselectortype = selectortype;
	treenode *const oldselectorexp = selectorexp;
	/*}}} */
	BOOL makedefault = TRUE;
	treenode *selectionlist = RHSOf (tptr);
	const int joinlab = newlab ();
	int maxcase = 0;
	treenode *defaultp = NULL;
	/*{{{  initialise globals */
	defaultlab = NO_LABEL;
	defaultjumpdest = FALSE;
	selectorexp = LHSOf (tptr);
	selectortype = ntypeof (selectorexp);
	/* make sure that we don't call memalloc with zero bytes */
	casetable = (caseentry *) memalloc (sizeof (caseentry) * casesin (selectionlist) + 1);
	/*}}} */
	/*{{{  evaluate the selector, if neccessary */
	tpreexp (selectorexp);
	simplify (P_EXP, selectorexp);
	/*}}} */
	/*{{{  build up table of selections, and generate jumps into case body */
	{
		treenode *slist;
		for (slist = selectionlist; !EndOfList (slist); slist = NextItem (slist)) {
			treenode *thisselection = skipspecifications (ThisItem (slist));
			treenode *v = CondGuardOf (thisselection);
			const int l = newlab ();
			if (TagOf (v) == S_ELSE) {
				defaultlab = l;
				defaultp = ThisItem (slist);
				makedefault = FALSE;
			} else
				/*{{{  set up labels and values */
				for (; !EndOfList (v); v = NextItem (v)) {
					treenode *thisconstant = ThisItem (v);
					caseentry *caseentryptr = &(casetable[maxcase]);
					caseentryptr->label = l;
					caseentryptr->jumpdest = FALSE;
					caseentryptr->lowvalue = LoValOf (thisconstant);
					caseentryptr->highvalue = HiValOf (thisconstant);
					caseentryptr->selectionexp = thisconstant;
					caseentryptr->selectionp = ThisItem (slist);
					maxcase++;
				}
			/*}}} */
		}
		if (makedefault)
			defaultlab = newlab ();
#if 0
		sup_qsort (casetable, maxcase, sizeof (caseentry), fitsinword (selectortype) ? comparecases : doublecomparecases);
#else
		sup_qsort (casetable, maxcase, sizeof (caseentry), (bytesinscalar (selectortype) <= 4) ? comparecases : doublecomparecases);
#endif
		tjumptable (0, maxcase - 1, FALSE);
	}
	/*}}} */
	/*{{{  generate case body */
	{
		int casesdone = 0;
		/*{{{  generate default process */
		setlab (defaultlab);
		if (makedefault) {
			if (NEED_ERRORS)	/* bug TS/2071 29/01/93 */
				tstop (tptr);
		} else {
			if (defaultjumpdest)
				genstartblock ();
			tselection (defaultp, joinlab);
		}
		/*}}} */
		while (casesdone < maxcase) {
			treenode *thisprocess;
			int i;
			BOOL jdest;
			/* Find a process to generate */
			for (i = 0; (i < maxcase) && (casetable[i].selectionp == NULL); i++)
				/* skip */ ;
			thisprocess = casetable[i].selectionp;
			/* Generate thisprocess */
			setlab (casetable[i].label);
			jdest = casetable[i].jumpdest;
			/*{{{  find and delete other entries for this process */
			{
				int j;
				for (j = i + 1; j < maxcase; j++)
					if (casetable[j].selectionp == thisprocess) {
						/* Delete the process, so we only generate it once */
						jdest = jdest | casetable[j].jumpdest;
						casetable[j].selectionp = NULL;
						casesdone++;
					}
			}
			/*}}} */
			if (jdest)
				genstartblock ();
			tselection (thisprocess, joinlab);
			casetable[i].selectionp = NULL;
			casesdone++;
		}
		setlab (joinlab);
		genstartblock ();
	}
	/*}}} */
	/*{{{  restore globals */
	memfree (casetable);
	casetable = oldcasetable;
	defaultlab = olddefaultlab;
	defaultjumpdest = olddefaultjumpdest;
	selectortype = oldselectortype;
	selectorexp = oldselectorexp;
	/*}}} */
}