[project @ 1996-01-11 14:06:51 by partain]
[ghc-hetmet.git] / ghc / compiler / yaccParser / infix.c
1 /*
2  *      Infix operator stuff -- modified from LML
3  */
4
5 #include <stdio.h>
6
7 #include "hspincl.h"
8 #ifdef DPH
9 #include "hsparser-DPH.tab.h"
10 #else
11 #include "hsparser.tab.h"
12 #endif
13 #include "constants.h"
14 #include "utils.h"
15
16 static short iscope = 1;
17
18 static struct infix {
19     char *iname;
20     short ilen;
21     short ifixity;
22     short iprecedence;
23 } infixtab[INFIX_SCOPES][MAX_INFIX] =
24   {
25   /*
26         Name            Len     Fixity          Precedence
27   */
28         "$",            1,      INFIXR,         0,
29         ":=",           2,      INFIX,          1,
30         "||",           2,      INFIXR,         2,
31         "&&",           2,      INFIXR,         3,
32         "==",           2,      INFIX,          4,
33         "/=",           2,      INFIX,          4,
34         "<",            1,      INFIX,          4,
35         "<=",           2,      INFIX,          4,
36         ">",            1,      INFIX,          4,
37         ">=",           2,      INFIX,          4,
38         "elem",         4,      INFIX,          4,
39         "notElem",      7,      INFIX,          4,
40         "\\\\",         2,      INFIX,          5,
41         ":",            1,      INFIXR,         5,
42         "++",           2,      INFIXR,         5,
43         "+",            1,      INFIXL,         6,
44         "-",            1,      INFIXL,         6,
45         ":+",           2,      INFIX,          6,
46         "*",            1,      INFIXL,         7,
47         "/",            1,      INFIXL,         7,
48         "mod",          3,      INFIXL,         7,
49         "div",          3,      INFIXL,         7,
50         "rem",          3,      INFIXL,         7,
51         "quot",         4,      INFIXL,         7,
52         ":%",           2,      INFIXL,         7, /* possibly wrong; should be omitted? */
53         "%",            1,      INFIXL,         7,
54         "**",           2,      INFIXR,         8,
55         "^",            1,      INFIXR,         8,
56         "^^",           2,      INFIXR,         8,
57         "!",            1,      INFIXL,         9,
58         "!!",           2,      INFIXL,         9,
59         "//",           2,      INFIXL,         9,
60         ".",            1,      INFIXR,         9
61 };
62
63
64 #define NFIX 31                                         /* The number of predefined operators */
65 #define ninfix (ninfixtab[iscope])
66 static int ninfixtab[INFIX_SCOPES] = {NFIX,0};          /* # of predefined operators */
67 static char infixstr[MAX_ISTR];
68 static char *infixp = infixstr;
69
70 /* An "iscope" is an "infix scope": the scope of infix declarations
71    (either the main module or an interface) */
72
73 void
74 enteriscope()
75 {
76   if(++iscope > INFIX_SCOPES)
77     {
78       char errbuf[ERR_BUF_SIZE];
79       sprintf(errbuf,"Too many infix scopes (> %d)\n",INFIX_SCOPES);
80     }
81   ninfix = 0;
82 }
83
84 #if 0
85 /* UNUSED */
86 void
87 exitiscope()
88 {
89   --iscope;
90 }
91 #endif
92
93 void
94 exposeis()
95 {
96   int i;
97   --iscope;
98
99   for (i=0; i < ninfixtab[iscope+1]; ++i)
100     {
101       struct infix *ip = infixtab[iscope+1] + i;
102       makeinfix(install_literal(ip->iname),ip->ifixity,ip->iprecedence);
103     }
104 }
105
106
107 static int
108 ionelookup(id name, int iscope)
109 {
110   int i;
111   char *iname = id_to_string(name);
112
113   for(i = 0; i < ninfixtab[iscope]; i++)
114     {
115       if(strcmp(iname,infixtab[iscope][i].iname)==0)
116         return(i);
117     }
118
119   return(-1);
120 }
121
122
123 struct infix *
124 infixlookup(name)
125   id name;
126 {
127   int i;
128   for (i=iscope; i >= 0; --i)
129     {
130      int n = ionelookup(name,i);
131       if (n >= 0)
132         return (infixtab[i]+n);
133     }
134   return (NULL);
135 }
136
137 int
138 nfixes()
139 {
140         return ninfix;
141 }
142
143 char *
144 fixop(int n)
145 {
146         return infixtab[iscope][n].iname;
147 }
148
149 char *
150 fixtype(int n)
151 {
152         switch(infixtab[iscope][n].ifixity) {
153         case INFIXL:
154                    return "infixl";
155
156         case INFIXR:
157                    return "infixr";
158
159         case INFIX:
160                  return "infix";
161
162         default : return 0;
163         /* Why might it return 0 ?? (WDP 94/11) */
164         }
165 }
166
167 #if 0
168 /* UNUSED? */
169 int
170 fixity(n)
171   int n;
172 {
173 #ifdef HSP_DEBUG
174   fprintf(stderr,"fixity of %s (at %d) is %d\n",infixtab[iscope][n].iname,n,infixtab[iscope][n].ifixity);
175 #endif
176   return(n < 0? INFIXL: infixtab[iscope][n].ifixity);
177 }
178 #endif /* 0 */
179
180
181 long int
182 precedence(n)
183   int n;
184 {
185 #ifdef HSP_DEBUG
186   fprintf(stderr,"precedence of %s (at %d) is %d\n",infixtab[iscope][n].iname,n,infixtab[iscope][n].iprecedence);
187 #endif
188   return(n < 0? 9: infixtab[iscope][n].iprecedence);
189 }
190
191
192 int
193 pfixity(ip)
194   struct infix *ip;
195 {
196 #ifdef HSP_DEBUG
197   fprintf(stderr,"fixity of %s is %d\n",ip->iname,ip->ifixity);
198 #endif
199   return(ip == NULL? INFIXL: ip->ifixity);
200 }
201
202 int
203 pprecedence(ip)
204   struct infix *ip;
205 {
206 #ifdef HSP_DEBUG
207   fprintf(stderr,"precedence of %s (at %d) is %d\n",ip->iname,ip->iprecedence);
208 #endif
209   return(ip == NULL? 9: ip->iprecedence);
210 }
211
212
213 void
214 makeinfix(ssi, fixity, precedence)
215   id ssi;
216   int fixity, precedence;
217 {
218     register int i, l;
219     char s[1000];
220     char *ss = id_to_string(ssi);
221
222     for(i=0; i < ninfix; ++i)
223       {
224         if(strcmp(ss,infixtab[iscope][i].iname)==0)
225           {
226             /* Allow duplicate definitions if they are identical */
227             if(infixtab[iscope][i].ifixity!=fixity || 
228                infixtab[iscope][i].iprecedence!=precedence )
229               {
230                 char errbuf[ERR_BUF_SIZE];
231                 sprintf(errbuf,"(%s) already declared to be %s %d\n",
232                         ss,
233                         fixtype(i),
234                         infixtab[iscope][i].iprecedence);
235                 hsperror(errbuf);
236               }
237             return;
238           }
239       }
240
241     strcpy(s, ss);
242     l = strlen(s);
243     s[l] = 0;
244
245     if (ninfix >= MAX_INFIX || infixp+l+1 >= &infixstr[MAX_ISTR]) {
246         char errbuf[ERR_BUF_SIZE];
247         sprintf(errbuf,"Too many Infix identifiers (> %d)",MAX_INFIX);
248         hsperror(errbuf);
249     }
250
251 #ifdef HSP_DEBUG
252     fprintf(stderr,"adding %s (was %s), fixity=%d, prec=%d\n",s,ss,fixity,precedence);
253 #endif
254     infixtab[iscope][ninfix].iname = infixp;
255     strcpy(infixp, s);
256     infixp += l+1;
257     infixtab[iscope][ninfix].ifixity = fixity;
258     infixtab[iscope][ninfix].iprecedence = precedence;
259     infixtab[iscope][ninfix].ilen = l-1;
260     ninfix++;
261 }