/* Routines to do substitutions, replacing one pattern with another */
/* eg, replace an expression of the from x-x by 0 or x+x by 2*x */

#include "evalint.h"

subst *make_sub(pat, rep)
char *pat, *rep;
{
    register subst *sub;

    if (sub = ALLOC(subst))
    {
	if (sub->pat = make_pattern(pat))
	{
	    if (sub->rep = compile(rep))
	    {
		/* Add the replacement's vars to the list in the pattern */
		/* (if there are any missing) */
		if (make_var_list(sub->rep, &sub->pat->vl)) return(sub);
		free_expr(sub->rep);
	    }
	    free_pattern(sub->pat);
	}
	FREE(subst, sub);
    }
    return(NULL);
}

void free_sub(sub)
subst *sub;
{
    free_expr(sub->rep);
    free_pattern(sub->pat);
    FREE(subst, sub);
}

/* If value matches pattern, do substitution, otherwise return NULL */
value substitute(sub, expr)
subst *sub;
value expr;
{
    value res;

    if (!match_pattern(sub->pat, expr)) return(NULL);
    else
    {	/* Match pattern leaves the variables in the pattern (and the replacement)
	  created, hence an eval on the replacement expression will do the required
	  substitution */
	res = _eval(sub->rep, VAR | NORED | PAT);
	free_vars(&sub->pat->vl);
	return(res);
    }
}

