Commit | Line | Data |
---|---|---|
cf27e488 TL |
1 | # ifndef EXIT |
2 | # define EXIT exit | |
3 | # endif | |
4 | ||
5 | int nerrors = 0; /* number of errors */ | |
6 | ||
7 | NODE *NIL; /* pointer which always has 0 in it */ | |
8 | ||
9 | NODE *lastfree; /* pointer to last free node; (for allocator) */ | |
10 | ||
11 | /* VARARGS1 */ | |
12 | uerror( s, a ) char *s; { /* nonfatal error message */ | |
13 | /* the routine where is different for pass 1 and pass 2; | |
14 | /* it tells where the error took place */ | |
15 | ||
16 | ++nerrors; | |
17 | where('u'); | |
18 | fprintf( stderr, s, a ); | |
19 | fprintf( stderr, "\n" ); | |
20 | if( nerrors > 30 ) cerror( "too many errors"); | |
21 | } | |
22 | ||
23 | /* VARARGS1 */ | |
24 | cerror( s, a, b, c ) char *s; { /* compiler error: die */ | |
25 | where('c'); | |
26 | if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */ | |
27 | fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" ); | |
28 | } | |
29 | else { | |
30 | fprintf( stderr, "compiler error: " ); | |
31 | fprintf( stderr, s, a, b, c ); | |
32 | fprintf( stderr, "\n" ); | |
33 | } | |
34 | EXIT(1); | |
35 | } | |
36 | ||
37 | /* VARARGS1 */ | |
38 | werror( s, a, b ) char *s; { /* warning */ | |
39 | where('w'); | |
40 | fprintf( stderr, "warning: " ); | |
41 | fprintf( stderr, s, a, b ); | |
42 | fprintf( stderr, "\n" ); | |
43 | } | |
44 | ||
45 | tinit(){ /* initialize expression tree search */ | |
46 | ||
47 | NODE *p; | |
48 | ||
49 | for( p=node; p<= &node[TREESZ-1]; ++p ) p->op = FREE; | |
50 | lastfree = node; | |
51 | ||
52 | } | |
53 | ||
54 | # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1) | |
55 | ||
56 | NODE * | |
57 | talloc(){ | |
58 | NODE *p, *q; | |
59 | ||
60 | q = lastfree; | |
61 | for( p = TNEXT(q); p!=q; p= TNEXT(p)) | |
62 | if( p->op ==FREE ) return(lastfree=p); | |
63 | ||
64 | cerror( "out of tree space; simplify expression"); | |
65 | /* NOTREACHED */ | |
66 | } | |
67 | ||
68 | tcheck(){ /* ensure that all nodes have been freed */ | |
69 | ||
70 | NODE *p; | |
71 | ||
72 | if( !nerrors ) | |
73 | for( p=node; p<= &node[TREESZ-1]; ++p ) | |
74 | if( p->op != FREE ) cerror( "wasted space: %o", p ); | |
75 | tinit(); | |
76 | } | |
77 | tfree( p ) NODE *p; { | |
78 | /* free the tree p */ | |
79 | extern tfree1(); | |
80 | ||
81 | if( p->op != FREE ) walkf( p, tfree1 ); | |
82 | ||
83 | } | |
84 | ||
85 | tfree1(p) NODE *p; { | |
86 | if( p == 0 ) cerror( "freeing blank tree!"); | |
87 | else p->op = FREE; | |
88 | } | |
89 | ||
90 | fwalk( t, f, down ) register NODE *t; int (*f)(); { | |
91 | ||
92 | int down1, down2; | |
93 | ||
94 | more: | |
95 | down1 = down2 = 0; | |
96 | ||
97 | (*f)( t, down, &down1, &down2 ); | |
98 | ||
99 | switch( optype( t->op ) ){ | |
100 | ||
101 | case BITYPE: | |
102 | fwalk( t->left, f, down1 ); | |
103 | t = t->right; | |
104 | down = down2; | |
105 | goto more; | |
106 | ||
107 | case UTYPE: | |
108 | t = t->left; | |
109 | down = down1; | |
110 | goto more; | |
111 | ||
112 | } | |
113 | } | |
114 | ||
115 | walkf( t, f ) register NODE *t; int (*f)(); { | |
116 | register opty; | |
117 | ||
118 | opty = optype(t->op); | |
119 | ||
120 | if( opty != LTYPE ) walkf( t->left, f ); | |
121 | if( opty == BITYPE ) walkf( t->right, f ); | |
122 | (*f)( t ); | |
123 | } | |
124 | ||
125 | ||
126 | ||
127 | int dope[ DSIZE ]; | |
128 | char *opst[DSIZE]; | |
129 | ||
130 | struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { | |
131 | ||
132 | NAME, "NAME", LTYPE, | |
133 | STRING, "STRING", LTYPE, | |
134 | REG, "REG", LTYPE, | |
135 | OREG, "OREG", LTYPE, | |
136 | ICON, "ICON", LTYPE, | |
137 | FCON, "FCON", LTYPE, | |
138 | CCODES, "CCODES", LTYPE, | |
139 | UNARY MINUS, "U-", UTYPE, | |
140 | UNARY MUL, "U*", UTYPE, | |
141 | UNARY AND, "U&", UTYPE, | |
142 | UNARY CALL, "UCALL", UTYPE|CALLFLG, | |
143 | UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, | |
144 | NOT, "!", UTYPE|LOGFLG, | |
145 | COMPL, "~", UTYPE, | |
146 | FORCE, "FORCE", UTYPE, | |
147 | INIT, "INIT", UTYPE, | |
148 | SCONV, "SCONV", UTYPE, | |
149 | PCONV, "PCONV", UTYPE, | |
150 | PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, | |
151 | ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, | |
152 | MINUS, "-", BITYPE|FLOFLG|SIMPFLG, | |
153 | ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
154 | MUL, "*", BITYPE|FLOFLG|MULFLG, | |
155 | ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, | |
156 | AND, "&", BITYPE|SIMPFLG|COMMFLG, | |
157 | ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, | |
158 | QUEST, "?", BITYPE, | |
159 | COLON, ":", BITYPE, | |
160 | ANDAND, "&&", BITYPE|LOGFLG, | |
161 | OROR, "||", BITYPE|LOGFLG, | |
162 | CM, ",", BITYPE, | |
163 | COMOP, ",OP", BITYPE, | |
164 | ASSIGN, "=", BITYPE|ASGFLG, | |
165 | DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, | |
166 | ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, | |
167 | MOD, "%", BITYPE|DIVFLG, | |
168 | ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, | |
169 | LS, "<<", BITYPE|SHFFLG, | |
170 | ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, | |
171 | RS, ">>", BITYPE|SHFFLG, | |
172 | ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, | |
173 | OR, "|", BITYPE|COMMFLG|SIMPFLG, | |
174 | ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
175 | ER, "^", BITYPE|COMMFLG|SIMPFLG, | |
176 | ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
177 | INCR, "++", BITYPE|ASGFLG, | |
178 | DECR, "--", BITYPE|ASGFLG, | |
179 | STREF, "->", BITYPE, | |
180 | CALL, "CALL", BITYPE|CALLFLG, | |
181 | FORTCALL, "FCALL", BITYPE|CALLFLG, | |
182 | EQ, "==", BITYPE|LOGFLG, | |
183 | NE, "!=", BITYPE|LOGFLG, | |
184 | LE, "<=", BITYPE|LOGFLG, | |
185 | LT, "<", BITYPE|LOGFLG, | |
186 | GE, ">", BITYPE|LOGFLG, | |
187 | GT, ">", BITYPE|LOGFLG, | |
188 | UGT, "UGT", BITYPE|LOGFLG, | |
189 | UGE, "UGE", BITYPE|LOGFLG, | |
190 | ULT, "ULT", BITYPE|LOGFLG, | |
191 | ULE, "ULE", BITYPE|LOGFLG, | |
192 | ARS, "A>>", BITYPE, | |
193 | TYPE, "TYPE", LTYPE, | |
194 | LB, "[", BITYPE, | |
195 | CBRANCH, "CBRANCH", BITYPE, | |
196 | FLD, "FLD", UTYPE, | |
197 | PMCONV, "PMCONV", BITYPE, | |
198 | PVCONV, "PVCONV", BITYPE, | |
199 | RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, | |
200 | CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, | |
201 | GOTO, "GOTO", UTYPE, | |
202 | STASG, "STASG", BITYPE|ASGFLG, | |
203 | STARG, "STARG", UTYPE, | |
204 | STCALL, "STCALL", BITYPE|CALLFLG, | |
205 | UNARY STCALL, "USTCALL", UTYPE|CALLFLG, | |
206 | ||
207 | -1, 0 | |
208 | }; | |
209 | ||
210 | mkdope(){ | |
211 | register struct dopest *q; | |
212 | ||
213 | for( q = indope; q->dopeop >= 0; ++q ){ | |
214 | dope[q->dopeop] = q->dopeval; | |
215 | opst[q->dopeop] = q->opst; | |
216 | } | |
217 | } | |
218 | tprint( t ) TWORD t; { /* output a nice description of the type of t */ | |
219 | ||
220 | static char * tnames[] = { | |
221 | "undef", | |
222 | "farg", | |
223 | "char", | |
224 | "short", | |
225 | "int", | |
226 | "long", | |
227 | "float", | |
228 | "double", | |
229 | "strty", | |
230 | "unionty", | |
231 | "enumty", | |
232 | "moety", | |
233 | "uchar", | |
234 | "ushort", | |
235 | "unsigned", | |
236 | "ulong", | |
237 | "?", "?" | |
238 | }; | |
239 | ||
240 | for(;; t = DECREF(t) ){ | |
241 | ||
242 | if( ISPTR(t) ) printf( "PTR " ); | |
243 | else if( ISFTN(t) ) printf( "FTN " ); | |
244 | else if( ISARY(t) ) printf( "ARY " ); | |
245 | else { | |
246 | printf( "%s", tnames[t] ); | |
247 | return; | |
248 | } | |
249 | } | |
250 | } |