3 extern out(char *, ...);
4 extern error(char *, ...);
10 /* All the functions in this file will be called by the parser.
13 extern char *strindex();
15 static struct Op_info { char *name, *type; }
16 op_info[ MAX_OPERANDS] = { { 0, 0}};
18 static int n_ops = 0; /* Number of opertands of current
19 * assembly instruction.
21 static char *assem_instr = 0; /* Name of the current assembly instr */
22 static Bool restriction = FALSE; /* Is there a restriction on the
27 save_instr( instr, len)
31 assem_instr = Salloc( instr, len + 1);
38 op_info[ n_ops].name = Salloc( name, len + 1);
45 op_info[ n_ops].type = Salloc( type, len + 1);
51 out( "%s_instr", assem_instr);
54 save_mnem( assem_instr);
63 out( " %s", op_info[0].name);
64 for ( i = 1; i < n_ops; i++)
65 out( ", %s", op_info[i].name);
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);
87 for ( i = 0; i < n_ops; i++)
88 if ( op_info[i].type != 0) {
91 out( " %s( %s)", op_info[i].type, op_info[i].name);
100 out( "else\nerror( \"No match for %s\");\n", assem_instr);
109 char *skip_string( str)
112 /* returns position after the first '"'-charcter, look out for '\' escape
116 for ( str++; *str != '"' || *(str-1) == '\\'; str++);
132 /* Ouput 'str', but keep track of the number of bytes and take care of
133 * conversions like %$.
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');
141 pr_text_with_conversions( str);
142 out( "fprint( outfile, \";\");");
147 out( "fprint( outfile, \"}\\n\");");
152 out( "fprint( outfile, \"else\\n\");");
157 out( "fprint( outfile, \"else {\\n\");");
163 out( "fprint( outfile, \"if\");");
164 pr_text_with_conversions( quest);
165 out( "fprint( outfile, \"{\\n\");");
172 out( "#include \"as.h\"\n");
173 out( "#include \"as_parser.h\"\n");
178 /* Free space, allocated during the parsing of an entry in 'as_table'.
183 if ( assem_instr != 0) {
188 for ( i = 0; i < n_ops; i++) {
189 free( op_info[i].name);
191 if ( op_info[i].type != 0) {
192 free( op_info[i].type);
201 /* Free space for the operands */
206 for ( i = 0; i < n_ops; i++) {
207 free( op_info[i].name);
209 if ( op_info[i].type != 0) {
210 free( op_info[i].type);
224 doprnt( outfile, fmt, pvar);
231 error(char *fmt, ...)
237 fprint( STDERR, "!! ERROR : ");
238 doprnt( STDERR, fmt, pvar);
239 fprint( STDERR, " !!\n");
251 fmt = va_arg(pvar, char *);
252 doprnt( outfile, fmt, pvar);
267 fmt = va_arg(pvar, char *);
268 fprint( STDERR, "!! ERROR : ");
269 doprnt( STDERR, fmt, pvar);
270 fprint( STDERR, " !!\n");
281 /**********************************/
283 char *mnemonic[ MAX_MNEMONICS];
289 if ( n_mnems == MAX_MNEMONICS)
290 error( "too many assembler instructions!! MAX_MNEMONICS = %d",
293 mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
299 /* Flush information in the array 'mnemonic'
304 quicksort( 0, n_mnems - 1);
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]);
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);
318 quicksort( lower, upper)
321 /* Sort the array 'mnemonic'.
330 key = mnemonic[lower];
334 while ( index1 < index2) {
338 while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
342 while ( strcmp( mnemonic[index2], key) > 0);
344 if ( index1 < index2) {
345 tmp = mnemonic[index2];
346 mnemonic[index2] = mnemonic[index1];
347 mnemonic[index1] = tmp;
351 mnemonic[lower] = mnemonic[index2];
352 mnemonic[index2] = key;
354 quicksort( lower, index2-1);
355 quicksort( index2+1, upper);