Pristine Ack-5.5
[Ack-5.5.git] / util / topgen / pattern.c
1 /* $Id: pattern.c,v 1.5 1994/06/24 10:42:16 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /* p a t t e r n . c
7  *
8  * Deals with the pattern stuff.
9  * it maintains a table of information about the patterns
10  * Functions : addpattern() and printpatterns()
11  */
12 # include <stdio.h>
13 # include <ctype.h>
14 # include "misc.h"
15 # include "symtab.h"
16
17 struct pattern {
18     char *p_constraint;                 /* constraint of this pattern */
19     int p_lineno,                       /* line number of constraint */
20         p_npat,                         /* # of instructions in pattern */
21         p_nrepl;                        /* # of instructions in replacement */
22 };
23
24 static struct pattern *pattable,        /* ptr to pattern array */
25                       *current,         /* ptr to first unoccupied el of
26                                          * pattern array
27                                          */
28                       *maxpat;          /* if beyond this, new space must
29                                          * be allocated
30                                          */
31
32 addpattern(str,l,np,nr) char *str; {
33     /*
34      * Just add a pattern to the list.
35      * "str" is the constraint, "l" is the line number,
36      * "np" is the number of instructions in the pattern,
37      * "nr" is the number of instructions in the replacement
38      * Space is allocated in chunks of 50
39      */
40     char *malloc(), *realloc();
41     register struct pattern *p;
42
43     if (!pattable) {            /* No space allocated yet */
44         pattable = (struct pattern *) malloc(50 * sizeof *pattable);
45         current = pattable;
46         maxpat = pattable + 50;
47     }
48     if (current >= maxpat) {    /* Allocate some new space */
49         p = pattable;
50         pattable = (struct pattern *) realloc(
51                 (char *) pattable,
52                 (unsigned) (sizeof *pattable * (50 + (maxpat - pattable))));
53         current = pattable + (current - p);
54         maxpat = pattable + (maxpat - p) + 50;
55     }
56     p = current++;
57     p->p_constraint = str;
58     p->p_lineno = l;
59     p->p_npat = np;
60     p->p_nrepl = nr;
61 }
62
63 static
64 prconstraint(str) char *str; {
65     /*
66      * prints a constraint, with variable names replaced
67      */
68     char c;
69     register char *p, *q;
70     struct symtab *name;
71
72     p = str;
73     while (*p) {
74         if (isupper(*p) || islower(*p) || *p == '_') {
75             /*
76              * Start of identifier
77              */
78             q = p + 1;
79             while (*q && (
80                    isupper(*q) || islower(*q) || isdigit(*q) || *q == '_')) {
81                 q++;
82             }
83             c = *q;
84             *q = '\0';
85             /* Temporarily let it end with null byte */
86             name = findident(p,LOOKING,&idtable);
87             if (name) {         /* yeah, it was a variable */
88                 fprintf(genc,"var[%d].value", name->s_num);
89             }
90             else if (!strcmp(p, "ANY")) {
91                 fputs("ANY.value", genc);
92             }
93             else fputs(p,genc);
94             /* Now replace null byte with whatever used to be there */
95             *q = c;
96             p = q;
97         }
98         else {
99             putc(*p,genc);
100             p++;
101         }
102     }
103 }
104
105 printpatterns() {
106     /*
107      * Prints the pattern_descr table and generates the routine
108      * "check_constraint"
109      */
110     register struct pattern *p;
111     register i;
112
113     p = pattable;
114     i = 1;
115     fputs("struct pattern_descr patterns[] = {\n", genc);
116     while (p != current) {
117         fprintf(genc," {%d,pat%d,%d,rep%d,},\n",
118                         p->p_npat, i, p->p_nrepl, i);
119         p++;
120         i++;
121     }
122     fputs("};\n", genc);
123     fputs("int\ncheck_constraint(patno){\n\tint r;\n\tswitch(patno){\n",genc);
124     p = pattable;
125     while (p < current) {
126         if (p->p_constraint) {
127             /* The pattern has a constraint */  
128             fprintf(genc,"\tcase %d :\n",p - pattable);
129             fprintf(genc,linedir,p->p_lineno,inpfile);  /* linedirective */
130             fputs("\tr = (",genc);
131             prconstraint(p->p_constraint);
132             fputs("); break;\n",genc);
133         }
134         p++;
135     }
136     fputs("\tdefault :\n\t\tr = 1;\n\t}\n\treturn r;\n}\n\n",genc);
137 }