130 lines
3.3 KiB
C
130 lines
3.3 KiB
C
|
/* p a t t e r n . c
|
||
|
*
|
||
|
* Deals with the pattern stuff.
|
||
|
* it maintains a table of information about the patterns
|
||
|
* Functions : addpattern() and printpatterns()
|
||
|
*/
|
||
|
# include <stdio.h>
|
||
|
# include <ctype.h>
|
||
|
# include "misc.h"
|
||
|
# include "symtab.h"
|
||
|
|
||
|
struct pattern {
|
||
|
char *p_constraint; /* constraint of this pattern */
|
||
|
int p_lineno, /* line number of constraint */
|
||
|
p_npat, /* # of instructions in pattern */
|
||
|
p_nrepl; /* # of instructions in replacement */
|
||
|
};
|
||
|
|
||
|
static struct pattern *pattable, /* ptr to pattern array */
|
||
|
*current, /* ptr to first unoccupied el of
|
||
|
* pattern array
|
||
|
*/
|
||
|
*maxpat; /* if beyond this, new space must
|
||
|
* be allocated
|
||
|
*/
|
||
|
|
||
|
addpattern(str,l,np,nr) char *str; {
|
||
|
/*
|
||
|
* Just add a pattern to the list.
|
||
|
* "str" is the constraint, "l" is the line number,
|
||
|
* "np" is the number of instructions in the pattern,
|
||
|
* "nr" is the number of instructions in the replacement
|
||
|
* Space is allocated in chunks of 50
|
||
|
*/
|
||
|
char *malloc(), *realloc();
|
||
|
register struct pattern *p;
|
||
|
|
||
|
if (!pattable) { /* No space allocated yet */
|
||
|
pattable = (struct pattern *) malloc(50 * sizeof *pattable);
|
||
|
current = pattable;
|
||
|
maxpat = pattable + 50;
|
||
|
}
|
||
|
if (current >= maxpat) { /* Allocate some new space */
|
||
|
p = pattable;
|
||
|
pattable = (struct pattern *) realloc(
|
||
|
(char *) pattable,
|
||
|
(unsigned) (sizeof *pattable * (50 + (maxpat - pattable))));
|
||
|
current = pattable + (current - p);
|
||
|
maxpat = pattable + (maxpat - p) + 50;
|
||
|
}
|
||
|
p = current++;
|
||
|
p->p_constraint = str;
|
||
|
p->p_lineno = l;
|
||
|
p->p_npat = np;
|
||
|
p->p_nrepl = nr;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
prconstraint(str) char *str; {
|
||
|
/*
|
||
|
* prints a constraint, with variable names replaced
|
||
|
*/
|
||
|
char c;
|
||
|
register char *p, *q;
|
||
|
struct symtab *name;
|
||
|
|
||
|
p = str;
|
||
|
while (*p) {
|
||
|
if (isupper(*p) || islower(*p) || *p == '_') {
|
||
|
/*
|
||
|
* Start of identifier
|
||
|
*/
|
||
|
q = p + 1;
|
||
|
while (*q && (
|
||
|
isupper(*q) || islower(*q) || isdigit(*q) || *q == '_')) {
|
||
|
q++;
|
||
|
}
|
||
|
c = *q;
|
||
|
*q = '\0';
|
||
|
/* Temporarily let it end with null byte */
|
||
|
name = findident(p,LOOKING,&idtable);
|
||
|
if (name) { /* yeah, it was a variable */
|
||
|
fprintf(genc,"var[%d].value", name->s_num);
|
||
|
}
|
||
|
else fputs(p,genc);
|
||
|
/* Now replace null byte with whatever used to be there */
|
||
|
*q = c;
|
||
|
p = q;
|
||
|
}
|
||
|
else {
|
||
|
putc(*p,genc);
|
||
|
p++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printpatterns() {
|
||
|
/*
|
||
|
* Prints the pattern_descr table and generates the routine
|
||
|
* "check_constraint"
|
||
|
*/
|
||
|
register struct pattern *p;
|
||
|
register i;
|
||
|
|
||
|
p = pattable;
|
||
|
i = 1;
|
||
|
fputs("struct pattern_descr patterns[] = {\n", genc);
|
||
|
while (p != current) {
|
||
|
fprintf(genc," {%d,pat%d,%d,rep%d,},\n",
|
||
|
p->p_npat, i, p->p_nrepl, i);
|
||
|
p++;
|
||
|
i++;
|
||
|
}
|
||
|
fputs("};\n", genc);
|
||
|
fputs("int\ncheck_constraint(patno){\n\tint r;\n\tswitch(patno){\n",genc);
|
||
|
p = pattable;
|
||
|
while (p < current) {
|
||
|
if (p->p_constraint) {
|
||
|
/* The pattern has a constraint */
|
||
|
fprintf(genc,"\tcase %d :\n",p - pattable);
|
||
|
fprintf(genc,linedir,p->p_lineno,inpfile); /* linedirective */
|
||
|
fputs("\tr = (",genc);
|
||
|
prconstraint(p->p_constraint);
|
||
|
fputs("); break;\n",genc);
|
||
|
}
|
||
|
p++;
|
||
|
}
|
||
|
fputs("\tdefault :\n\t\tr = 1;\n\t}\n\treturn r;\n}\n\n",genc);
|
||
|
}
|