Esempio n. 1
0
// Copy the nodes
Leaf * IntervallTree_bed::nodecopy(Leaf * &p) {
	Leaf * temp;
	if (p == NULL) {
		return p;
	} else {
		temp = new Leaf(p->get_start(), p->get_stop()); //TODO!
		temp->left = nodecopy(p->left);
		temp->right = nodecopy(p->right);
		return temp;
	}
}
Esempio n. 2
0
/*@-incondefs@*/
/*@null@*/ node *nodecopy(/*@null@*/ const node* n)
/*@=incondefs@*/
{
  node* np;
  if(!n) return 0;
  np = cons(n->opcode, nodecopy(n->lval), nodecopy(n->rval));
  np->constant = n->constant;
  np->optdata = n->optdata;
  np->width = n->width;
  return np;
}
Esempio n. 3
0
// Copy the nodes
nodeptr bstree::nodecopy(nodeptr &p)
{
	nodeptr temp;
	if (p==NULL)
		return p;
	else
	{
		temp = new node;
		temp->element = p->element;
		temp->left = nodecopy(p->left);
		temp->right = nodecopy(p->right);
		return temp;
	}
}
Esempio n. 4
0
/******************************************************************************
 *
 *	I N S T A L L _ A B B R E V S (char *name, node *n)
 *
 * Install a name as a hidden procedure with all the abbreviations implied by
 * specifications of the form: COM(MAND)
 *
 * With DEFPROC or DEFSTRING one can specify the new command or procedure
 * using COM(MAND) meaning that COM, COMM, COMMA, COMMAN and COMMAND are all
 * suitable forms of the command.  This routine generates all the
 * abbreviations and adds each as a HIDDEN_PROC to the global
 * symbol table with the value "n".
 *
 * WILL FAIL GIVEN COMM() ie empty optional part!!
 *
 ******************************************************************************
 */
value
install_abbrevs(char *name, node * n)
{
    value val;
    node *nw;
    char *p;

    if ((name = strcopy(name)) == CHARNIL)
	return exception("SYSERR  memory exhausted in install_abbrevs()");
    if ((p = strchr(name, '(')) != CHARNIL) {
	do {
	    *p = '\0';
	    if ((nw = nodecopy(n)) == NODENIL)
		return exception(
			       "SYSERR  memory exhausted in install_abbrevs()");
	    if (isexc(val = store_symbol(name, SYM_DEFINED, nw)))
		return (val);
	    else {
		*p = p[1];
		p++;
	    }
	}
	while (*p && *p != ')');
	return trueval;
    } else
	return (store_symbol(name, SYM_DEFINED, n));
}
Esempio n. 5
0
void optimizef(void)
{
  tuple* tp, *tpa, *tpb;
  atom* op;
  node* np;
  if(!flowoptimize) ick_lose(IE778, iyylineno, (const char *) NULL);
  for (tp = tuples; tp < tuples + ick_lineno; tp++) tp->abstainable = 0;
  /* abstainable holds whether a line's abstention status can change */
  for (op = oblist; op != NULL && op < obdex; op++) op->ignorable = 0;
  /* ignorable holds whether a variable's ignorance status can change */
  for (tp = tuples; tp < tuples + ick_lineno; tp++)
  {
    /* allow for warnings to be generated during flow optimisations */
    /* AIS: I marked tuples as only deliberately, so that it produced warnings
       when aliased in an unsafe way. However, tuples isn't realloced during
       optimisation, so we can safely ignore the warning for it produced
       here. */
    /*@-onlytrans@*/
    optuple = tp;
    /*@=onlytrans@*/
    if(tp->maybe) tp->abstainable = true;
    if(tp->exechance < 0) tp->initabstain = true;
    if(tp->exechance != 100 && tp->exechance != -100) tp->abstainable = true;
    if(tp->onceagainflag != onceagain_NORMAL) tp->abstainable = true;
    if(tp->type == ABSTAIN || tp->type == FROM)
    {
      tpa = tp->u.target - 1 + tuples;
      if(tpa->exechance >= 0) tpa->abstainable = true;
    }
    if(tp->type == REINSTATE)
    {
      tpa = tp->u.target - 1 + tuples;
      if(tpa->exechance < 0) tpa->abstainable = true;
    }
    if(tp->type == DISABLE || tp->type == MANYFROM)
    {
      for (tpa = tuples; tpa < tuples + ick_lineno; tpa++)
      {
	np = tp->u.node;
	if(tp->type == MANYFROM) np = np->rval;
	for(; np; np = np -> rval)
	  if(abstainmatch((int)np->constant, (int)tpa->type))
	    if(tpa->exechance >= 0) tpa->abstainable = true;
      }
    }
    if(tp->type == ENABLE)
    {
      for (tpa = tuples; tpa < tuples + ick_lineno; tpa++)
      {
	np = tp->u.node;
	for(; np; np = np -> rval)
	  if(abstainmatch((int)np->constant, (int)tpa->type))
	    if(tpa->exechance < 0) tpa->abstainable = true;
      }
    }
    if(tp->type == GETS && ick_Base == 2 && !opoverused)
      checknodeactbits(tp->u.node->rval);
    /* If optdata shows that the value must always fit in the variable,
       and the variable cannot be ignored, ick_assign can be replaced by the
       cheaper =. */
    if(tp->type == IGNORE)
    {
      for (np = tp->u.node; np; np = np->rval)
      {
	for (op = oblist; op != NULL && op < obdex; op++)
	{
	  if(op->type == np->opcode && (unsigned long)op->intindex == np->constant)
	    op->ignorable = 1;
	}
      }
    }
    /* REMEMBERING variables has no effect on this code, because all
       variables are initially remembered anyway, and so an IGNORE would
       be needed (and caught above) to have an effect. */
  }
  /* There are some flow idioms that maybe should be optimized. The most
     common is the NEXTing idiom for if(), which looks like this:

         DO (1) NEXT
	 block 2
	 escape via NEXTING or COMEFROM
     (1) DO (2) NEXT
         DO FORGET #1
         block 1

	 and elsewhere in the program:
     (2) DO RESUME <1-or-2-condition>

     Recognizing this idiom is quite difficult because there are a number of
     problems and common variations.
     First, the FORGET might be placed elsewhere, or replaced with a higher
     FORGET later or a higher RESUME later. If there is, in fact, a RESUME #1
     as the ick_next NEXT-control statement, the idiom won't quite work properly.
     So to handle this, we need to push the original return address on the
     NEXT stack if block 1 is taken, unless the ick_next statement is a FORGET #1.
     Second, there may be abstentions or COME FROMs messing with control flow
     in the area. The flow optimizer ought to be able to detect this and not
     optimize the statement if true. (This means that a program which uses
     gerund abstention on NEXTING or RESUMING, or that uses computed COME FROM,
     will probably not benefit from this optimization). Third, how should a
     <1-or-2-condition> be detected? Throughout syslib, the most common
     condition to use is .5, which isn't inherently 1 or 2. The way round this
     seems to be to detect a <1-or-2-assignment> as the previous statement,
     again with checks for COME FROM and abstentions. (I treat MAYBE as a sort
     of abstention, albeit a temporally undecided one.) So ignorance of the
     relevant variable needs to be checked for also. The checks are done partly
     in optimizef() and partly in emit().
  */
  if(compucomesused||ick_Base!=2||opoverused) return;

  np = (node*) NULL;
  for (tp = tuples; tp < tuples + ick_lineno; tp++)
  {
    if(tp->type == GETS)
    {
/*      if(tp->u.node->rval->opcode == C_AND1ADD1 ||
	 tp->u.node->rval->opcode == C_2SUBAND1 ||
	 ((tp->u.node->rval->opcode == C_1PLUS ||
	   tp->u.node->rval->opcode == C_2MINUS) &&
	   tp->u.node->rval->rval->optdata == 1)) //debug for now */ if(0)
      {
	/* This won't catch all <1-or-2-expressions>, but will get
	   most of them. */
	if(tp->u.node->lval->opcode != SUB) np = tp->u.node->lval;
      }
      else if(np != NULL && nodessame(np, tp->u.node->lval)) np = (node*) NULL;
      if(tp->nextable) np = (node*) NULL;
      if(tp->maybe||tp->abstainable) np = (node*) NULL;
      if(tp->ncomefrom&&multithread) np = (node*) NULL;
      if(np)
      {	/* IGNORING np might prevent it getting its <1-or-2-value>. */
	atom* op2;
	int ignorable = 1;
	for(op2 = oblist; op2 != NULL && op2 < obdex; op2++)
	{
	  if(op2->type == np->opcode &&
	     (unsigned long)op2->intindex == np->constant)
	  {
	    ignorable &= op2->ignorable;
	  }
	}
	if(ignorable) np = (node*) NULL;
      }
      /* np will only have a nonnull value if it's a variable that must be
	 set to a <1-or-2-value> to reach line tp. Regardless of whether
         maybes have been parsed or not, either maybe or abstainable or
         both will be 1 on a MAYBE line. The last check is a precaution
         against MAYBE COME FROM sneakily modifying a variable (although
         I think it's unlikely that anyone would deliberately try to fool
         -f like this, it is INTERCAL after all!) */
    }
    if(tp->type == COME_FROM || tp->type == COMPUCOME) np = (node*) NULL;
    if(tp->type == NEXT)
    {
      tpa = tuples + tp->nexttarget - 1;
      if(tpa->type == NEXT && !tp->abstainable && !tpa->abstainable
	 && !tp->ncomefrom && !tpa->ncomefrom)
      {
	tpb = tuples + tpa->nexttarget - 1;
	if(tpb->type == RESUME && (/*(tpb->u.node->opcode == C_AND1ADD1 ||
				    tpb->u.node->opcode == C_2SUBAND1 ||
				    ((tpb->u.node->opcode == C_1PLUS ||
				      tpb->u.node->opcode == C_2MINUS) &&
				      tpb->u.node->rval->optdata == 1)) ||*/
				   (np != NULL && nodessame(tpb->u.node,np))) &&
				    !tpb->abstainable)
	  /* No COMING FROM a nonabstainable RESUME line! */
	{
	  tp->optversion = true;
	  free(tp->u.node);
	  tp->u.node = nodecopy(tpb->u.node);
	  /* If tp->u.node is 2, then the statement should translate to a
	     no-op (NEXT...NEXT...RESUME #2). However, if tp->u.node is 1,
	     the statement should translate to a NEXT to the line after the
	     one it's aiming for. As it's aiming for a NEXT, the solution is
	     to NEXT to the return label of the NEXT it's aiming for. This
	     won't trigger any COME FROMs or ONCE/AGAIN flags, or even MAYBEs,
	     on the commands missed out, so the code has checked that they
	     aren't there. */
	}
      }
      np = (node*) NULL;
    }
  }
  /*@-nullstate@*/ /* no tuples->u.node can't be null */
}
Esempio n. 6
0
// Copy a tree
void bstree::copy(nodeptr &p,nodeptr &p1)
{
	makeempty(p1);
	p1 = nodecopy(p);
}
Esempio n. 7
0
// Copy a tree
void IntervallTree_bed::copy(Leaf * &p, Leaf * &p1) {
	makeempty(p1);
	p1 = nodecopy(p);
}