Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / cg / nextem.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: nextem.c,v 2.4 1994/06/24 13:23:56 ceriel Exp $";
3 #endif
4
5 #include <em_spec.h>
6 #include <em_flag.h>
7 #include "assert.h"
8 #include "param.h"
9 #include "tables.h"
10 #include "types.h"
11 #include <cg_pattern.h>
12 #include "data.h"
13 #include "result.h"
14 #include "extern.h"
15
16 /*
17  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
18  * See the copyright notice in the ACK home directory, in the file "Copyright".
19  *
20  * Author: Hans van Staveren
21  */
22
23 #ifndef NDEBUG
24 #include <stdio.h>
25 extern char em_mnem[][4];
26 #endif
27
28 byte *trypat(bp,len) register byte *bp; {
29         register patlen,i;
30         result_t result;
31
32         getint(patlen,bp);
33         if (len == 3) {
34                 if (patlen < 3)
35                         return(0);
36         } else {
37                 if (patlen != len)
38                         return(0);
39         }
40         for(i=0;i<patlen;i++)
41                 if (emp[i].em_instr != (*bp++&BMASK))
42                         return(0);
43         for (i=0;i<patlen;i++)
44                 if (emp[i].em_optyp==OPNO)
45                         dollar[i].e_typ=EV_UNDEF;
46                 else if ((dollar[i].e_typ=argtyp(emp[i].em_instr))==EV_INT)
47                         dollar[i].e_v.e_con=emp[i].em_u.em_ioper;
48                 else
49                         dollar[i].e_v.e_str=emp[i].em_soper;
50         getint(i,bp);
51         if (i!=0) {
52                 struct emline *svp = saveemp;
53
54                 saveemp = emp;
55                 result = compute(&enodes[i]);
56                 if (result.e_typ != EV_INT || result.e_v.e_con == 0) {
57                         saveemp = svp;
58                         return(0);
59                 }
60         }
61 #ifndef NDEBUG
62         if (Debug) {
63                 fprintf(stderr,"Matched:");
64                 for (i=0;i<patlen;i++)
65                         fprintf(stderr," %3.3s",em_mnem[emp[i].em_instr-sp_fmnem]);
66                 fprintf(stderr,"\n");
67         }
68 #endif
69         saveemp = emp;
70         emp += patlen;
71         return(bp);
72 }
73
74 extern char em_flag[];
75
76 argtyp(mn) {
77
78         switch(em_flag[mn-sp_fmnem]&EM_PAR) {
79         case PAR_W:
80         case PAR_S:
81         case PAR_Z:
82         case PAR_O:
83         case PAR_N:
84         case PAR_L:
85         case PAR_F:
86         case PAR_R:
87         case PAR_C:
88                 return(EV_INT);
89         default:
90                 return(EV_STR);
91         }
92 }
93
94 byte *nextem(toplevel) {
95         register i;
96         short hash[3];
97         register byte *bp;
98         byte *cp;
99         int index;
100         register struct emline *ep;
101
102         if (toplevel) {
103                 if (nemlines && emp>emlines) {
104                         nemlines -= emp-emlines;
105                         for (i=0,ep=emlines;i<nemlines;i++)
106                                 *ep++ = *emp++;
107                         emp=emlines;
108                 }
109                 fillemlines();
110         }
111         hash[0] = emp[0].em_instr;
112         hash[1] = (hash[0]<<4) ^ emp[1].em_instr;
113         hash[2] = (hash[1]<<4) ^ emp[2].em_instr;
114         for (i=2;i>=0;i--) {
115                 index = pathash[hash[i]&BMASK];
116                 while (index != 0) {
117                         bp = &pattern[index];
118                         if ( bp[PO_HASH] == (hash[i]>>8))
119                                 if ((cp=trypat(&bp[PO_MATCH],i+1)) != 0)
120                                         return(cp);
121                         index = (bp[PO_NEXT]&BMASK) | (bp[PO_NEXT+1]<<8);
122                 }
123         }
124         return(0);
125 }