Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / as_parser / help.c
1 #if __STDC__
2 #include <stdarg.h>
3 extern out(char *, ...);
4 extern error(char *, ...);
5 #else
6 #include <varargs.h>
7 #endif
8 #include "decl.h"
9
10 /* All the functions in this file will be called by the parser.
11  */
12
13 extern char     *strindex();
14
15 static struct Op_info { char *name, *type; }
16                         op_info[ MAX_OPERANDS] = { { 0, 0}};
17
18 static int      n_ops = 0;              /* Number of opertands of current
19                                          * assembly instruction.
20                                          */
21 static char     *assem_instr = 0;       /* Name of the current assembly instr */
22 static Bool     restriction = FALSE;    /* Is there a restriction on the
23                                          * current operand?
24                                          */
25 File *outfile;
26
27 save_instr( instr, len)
28 char *instr;
29 int len;
30 {
31         assem_instr = Salloc( instr, len + 1);
32 }
33
34 save_name( name, len)
35 char *name;
36 int len;
37 {
38         op_info[ n_ops].name = Salloc( name, len + 1);
39 }
40
41 save_type( type, len)
42 char *type;
43 int len;
44 {
45         op_info[ n_ops].type = Salloc( type, len + 1);
46         restriction = TRUE;
47 }
48
49 pr_header()
50 {
51         out( "%s_instr", assem_instr);
52         param_list();
53         out( "{\n");
54         save_mnem( assem_instr);
55 }
56
57 param_list()
58 {
59         int i;
60
61         out( "(");
62         if ( n_ops > 0) {
63                 out( " %s", op_info[0].name);
64                 for ( i = 1; i < n_ops; i++) 
65                         out( ", %s", op_info[i].name);
66         }
67
68         out( ")\n");
69         if ( n_ops > 0) {
70                 out( "struct t_operand *%s", op_info[0].name);
71                 for ( i = 1; i < n_ops; i++) 
72                         out( ", *%s", op_info[i].name);
73                 out( ";\n");
74         }
75 }
76
77
78 pr_restriction()
79 {
80         int i;
81         Bool more = FALSE;
82
83         if ( !restriction)
84                 return;
85
86         out( "if ( ");
87         for ( i = 0; i < n_ops; i++)
88                 if ( op_info[i].type != 0) {
89                         if ( more)
90                                 out( " &&");
91                         out( " %s( %s)", op_info[i].type, op_info[i].name);
92                         more = TRUE;
93                 }
94         out( ") ");
95 }
96
97 pr_warning()
98 {
99         if ( restriction)
100                 out( "else\nerror( \"No match for %s\");\n", assem_instr);
101         restriction = FALSE;
102 }
103
104 clear_restriction()
105 {
106         restriction = FALSE;
107 }
108
109 char *skip_string( str)
110 char *str;
111
112 /* returns position after the first '"'-charcter, look out for '\' escape
113  * sequence
114  */
115 {
116         for ( str++; *str != '"' || *(str-1) == '\\'; str++);
117         return( str + 1);
118 }
119
120 pr_subroutine( str)
121 char *str;
122 {
123         out( "%s;\n", str);
124 }
125
126
127 #include <ctype.h>
128
129 pr_call( str)
130 char *str;
131
132 /* Ouput 'str', but keep track of the number of bytes and take care of
133  * conversions like %$.
134  */
135 {
136         if ( strncmp( "text", str, 4) == 0 && isdigit( *(str+4))) 
137                 out( "cur_pos += %d;\n", *(str+4) - '0');
138         else if ( strncmp( "reloc", str, 5) == 0 && isdigit( *(str+5)))
139                 out( "cur_pos += %d;\n", *(str+5) - '0');
140
141         pr_text_with_conversions( str);
142         out( "fprint( outfile, \";\");");
143 }
144
145 pr_end()
146 {
147         out( "fprint( outfile, \"}\\n\");");
148 }
149
150 pr_els()
151 {
152         out( "fprint( outfile, \"else\\n\");");
153 }
154
155 pr_else()
156 {
157         out( "fprint( outfile, \"else {\\n\");");
158 }
159
160 pr_question( quest)
161 char *quest;
162 {
163         out( "fprint( outfile, \"if\");");
164         pr_text_with_conversions( quest);
165         out( "fprint( outfile, \"{\\n\");");
166 }
167
168
169 init_table()
170 {
171         outfile = STDOUT;
172         out( "#include \"as.h\"\n");
173         out( "#include \"as_parser.h\"\n");
174 }
175
176 clean()
177
178 /* Free space, allocated during the parsing of an entry in 'as_table'.
179  */
180 {
181         int i;
182
183         if ( assem_instr != 0) {
184                 free( assem_instr);
185                 assem_instr = 0;
186         }
187
188         for ( i = 0; i < n_ops; i++) {
189                 free( op_info[i].name);
190                 op_info[i].name = 0;
191                 if ( op_info[i].type != 0) {
192                         free( op_info[i].type);
193                         op_info[i].type = 0;
194                 }
195         }
196         n_ops = 0;
197 }
198
199 operand_clean()
200
201 /* Free space for the operands */
202
203 {
204         int i;
205
206         for ( i = 0; i < n_ops; i++) {
207                 free( op_info[i].name);
208                 op_info[i].name = 0;
209                 if ( op_info[i].type != 0) {
210                         free( op_info[i].type);
211                         op_info[i].type = 0;
212                 }
213         }
214         n_ops = 0;
215 }
216
217 #if __STDC__
218 /*VARARGS*/
219 out(char *fmt, ...)
220 {
221         va_list pvar;
222
223         va_start(pvar, fmt);
224         doprnt( outfile, fmt, pvar);
225         va_end(pvar);
226 }
227
228 extern int nerrors;
229
230 /*VARARGS*/
231 error(char *fmt, ...)
232 {
233         va_list pvar;
234
235         nerrors++;
236         va_start(pvar, fmt);
237         fprint( STDERR, "!! ERROR :     ");
238         doprnt( STDERR, fmt, pvar);
239         fprint( STDERR, "       !!\n");
240         va_end(pvar);
241 }
242 #else
243 /*VARARGS*/
244 out(va_alist)
245 va_dcl
246 {
247         va_list pvar;
248         char *fmt;
249
250         va_start(pvar);
251         fmt = va_arg(pvar, char *);
252         doprnt( outfile, fmt, pvar);
253         va_end(pvar);
254 }
255
256 extern int nerrors;
257
258 /*VARARGS*/
259 error(va_alist)
260 va_dcl
261 {
262         char *fmt;
263         va_list pvar;
264
265         nerrors++;
266         va_start(pvar);
267         fmt = va_arg(pvar, char *);
268         fprint( STDERR, "!! ERROR :     ");
269         doprnt( STDERR, fmt, pvar);
270         fprint( STDERR, "       !!\n");
271         va_end(pvar);
272 }
273 #endif
274
275 inc_ops()
276 {
277         n_ops++;
278 }
279
280
281 /**********************************/
282
283 char *mnemonic[ MAX_MNEMONICS];
284 int n_mnems = 0;
285
286 save_mnem( mnem)
287 char *mnem;
288 {
289         if ( n_mnems == MAX_MNEMONICS)
290                 error( "too many assembler instructions!! MAX_MNEMONICS = %d",
291                         MAX_MNEMONICS);
292         else
293                 mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
294 }
295
296
297 end_table()
298
299 /* Flush information in the array 'mnemonic'
300  */
301 {
302         int i;
303
304         quicksort( 0, n_mnems - 1);
305         
306         out( "char *mnemonic[] = {\n");
307         for ( i = 0; i < n_mnems - 1; i++)
308                 out( "\t\"%s\",\n", mnemonic[i]);
309         out( "\t\"%s\"};\n\n", mnemonic[ n_mnems-1]);
310
311         out( "int (*instruction[])() = {\n");
312         for ( i = 0; i < n_mnems - 1; i++)
313                 out( "\t%s_instr,\n", mnemonic[i]);
314         out( "\t%s_instr};\n\n", mnemonic[ n_mnems-1]);
315         out( "int n_mnems = %d;\n", n_mnems);
316 }
317
318 quicksort( lower, upper)
319 int lower, upper;
320
321 /* Sort the array 'mnemonic'.
322  */
323 {
324         char *key, *tmp;
325         int index1, index2;
326
327         if ( lower >= upper)
328                 return;
329
330         key = mnemonic[lower];
331         index1 = lower;
332         index2 = upper+1;
333
334         while ( index1 < index2) {
335
336                 do
337                         index1++;
338                 while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
339
340                 do
341                         index2--;
342                 while ( strcmp( mnemonic[index2], key) > 0);
343
344                 if ( index1 < index2) {
345                         tmp = mnemonic[index2];
346                         mnemonic[index2] = mnemonic[index1];
347                         mnemonic[index1] = tmp;
348                 }
349         }
350
351         mnemonic[lower] = mnemonic[index2];
352         mnemonic[index2] = key;
353
354         quicksort( lower, index2-1);
355         quicksort( index2+1, upper);
356 }