ack/util/ceg/as_parser/help.c

360 lines
5.6 KiB
C
Raw Normal View History

#include <stdlib.h>
#include <string.h>
#if __STDC__
#include <stdarg.h>
extern out(char *, ...);
extern error(char *, ...);
#else
#include <varargs.h>
#endif
1987-11-20 11:12:07 +00:00
#include "decl.h"
1988-01-07 16:09:30 +00:00
/* All the functions in this file will be called by the parser.
*/
1987-11-20 11:12:07 +00:00
extern char *strindex();
1991-05-16 13:08:32 +00:00
static struct Op_info { char *name, *type; }
1987-11-20 11:12:07 +00:00
op_info[ MAX_OPERANDS] = { { 0, 0}};
1988-01-07 16:09:30 +00:00
static int n_ops = 0; /* Number of opertands of current
* assembly instruction.
*/
static char *assem_instr = 0; /* Name of the current assembly instr */
static Bool restriction = FALSE; /* Is there a restriction on the
* current operand?
*/
1987-11-20 11:12:07 +00:00
File *outfile;
save_instr( instr, len)
char *instr;
int len;
{
assem_instr = Salloc( instr, len + 1);
}
save_name( name, len)
char *name;
int len;
{
op_info[ n_ops].name = Salloc( name, len + 1);
}
save_type( type, len)
char *type;
int len;
{
op_info[ n_ops].type = Salloc( type, len + 1);
restriction = TRUE;
}
pr_header()
{
out( "%s_instr", assem_instr);
param_list();
out( "{\n");
save_mnem( assem_instr);
}
param_list()
{
int i;
out( "(");
if ( n_ops > 0) {
out( " %s", op_info[0].name);
for ( i = 1; i < n_ops; i++)
out( ", %s", op_info[i].name);
}
out( ")\n");
if ( n_ops > 0) {
out( "struct t_operand *%s", op_info[0].name);
for ( i = 1; i < n_ops; i++)
out( ", *%s", op_info[i].name);
out( ";\n");
}
}
pr_restriction()
{
int i;
Bool more = FALSE;
if ( !restriction)
return;
out( "if ( ");
for ( i = 0; i < n_ops; i++)
if ( op_info[i].type != 0) {
if ( more)
out( " &&");
out( " %s( %s)", op_info[i].type, op_info[i].name);
more = TRUE;
}
out( ") ");
}
pr_warning()
{
if ( restriction)
out( "else\nerror( \"No match for %s\");\n", assem_instr);
restriction = FALSE;
}
clear_restriction()
{
restriction = FALSE;
}
char *skip_string( str)
char *str;
1988-01-07 16:09:30 +00:00
/* returns position after the first '"'-charcter, look out for '\' escape
* sequence
*/
1987-11-20 11:12:07 +00:00
{
for ( str++; *str != '"' || *(str-1) == '\\'; str++);
return( str + 1);
}
pr_subroutine( str)
char *str;
{
out( "%s;\n", str);
}
#include <ctype.h>
pr_call( str)
char *str;
1988-01-07 16:09:30 +00:00
/* Ouput 'str', but keep track of the number of bytes and take care of
* conversions like %$.
*/
1987-11-20 11:12:07 +00:00
{
if ( strncmp( "text", str, 4) == 0 && isdigit( *(str+4)))
out( "cur_pos += %d;\n", *(str+4) - '0');
else if ( strncmp( "reloc", str, 5) == 0 && isdigit( *(str+5)))
out( "cur_pos += %d;\n", *(str+5) - '0');
pr_text_with_conversions( str);
out( "fprint( outfile, \";\");");
}
pr_end()
{
out( "fprint( outfile, \"}\\n\");");
}
pr_els()
{
out( "fprint( outfile, \"else\\n\");");
}
pr_else()
{
out( "fprint( outfile, \"else {\\n\");");
}
pr_question( quest)
char *quest;
{
out( "fprint( outfile, \"if\");");
pr_text_with_conversions( quest);
out( "fprint( outfile, \"{\\n\");");
}
init_table()
{
outfile = STDOUT;
out( "#include \"as.h\"\n");
out( "#include \"as_parser.h\"\n");
}
clean()
1988-01-07 16:09:30 +00:00
/* Free space, allocated during the parsing of an entry in 'as_table'.
*/
1987-11-20 11:12:07 +00:00
{
int i;
if ( assem_instr != 0) {
free( assem_instr);
assem_instr = 0;
}
for ( i = 0; i < n_ops; i++) {
free( op_info[i].name);
op_info[i].name = 0;
if ( op_info[i].type != 0) {
free( op_info[i].type);
op_info[i].type = 0;
}
}
n_ops = 0;
}
operand_clean()
1988-01-07 16:09:30 +00:00
/* Free space for the operands */
1987-11-20 11:12:07 +00:00
{
int i;
for ( i = 0; i < n_ops; i++) {
free( op_info[i].name);
op_info[i].name = 0;
if ( op_info[i].type != 0) {
free( op_info[i].type);
op_info[i].type = 0;
}
}
n_ops = 0;
}
#if __STDC__
/*VARARGS*/
out(char *fmt, ...)
{
va_list pvar;
va_start(pvar, fmt);
doprnt( outfile, fmt, pvar);
va_end(pvar);
}
extern int nerrors;
/*VARARGS*/
error(char *fmt, ...)
{
va_list pvar;
nerrors++;
va_start(pvar, fmt);
fprint( STDERR, "!! ERROR : ");
doprnt( STDERR, fmt, pvar);
fprint( STDERR, " !!\n");
va_end(pvar);
}
#else
1988-08-19 09:22:07 +00:00
/*VARARGS*/
out(va_alist)
va_dcl
1987-11-20 11:12:07 +00:00
{
1988-08-19 09:22:07 +00:00
va_list pvar;
char *fmt;
va_start(pvar);
fmt = va_arg(pvar, char *);
doprnt( outfile, fmt, pvar);
va_end(pvar);
1987-11-20 11:12:07 +00:00
}
1988-09-09 11:36:57 +00:00
extern int nerrors;
1988-08-19 09:22:07 +00:00
/*VARARGS*/
error(va_alist)
va_dcl
1987-11-20 11:12:07 +00:00
{
1988-08-19 09:22:07 +00:00
char *fmt;
va_list pvar;
1988-09-09 11:36:57 +00:00
nerrors++;
1988-08-19 09:22:07 +00:00
va_start(pvar);
fmt = va_arg(pvar, char *);
1987-11-20 11:12:07 +00:00
fprint( STDERR, "!! ERROR : ");
1988-08-19 09:22:07 +00:00
doprnt( STDERR, fmt, pvar);
1987-11-20 11:12:07 +00:00
fprint( STDERR, " !!\n");
1988-08-19 09:22:07 +00:00
va_end(pvar);
1987-11-20 11:12:07 +00:00
}
#endif
1987-11-20 11:12:07 +00:00
inc_ops()
{
n_ops++;
}
/**********************************/
char *mnemonic[ MAX_MNEMONICS];
int n_mnems = 0;
save_mnem( mnem)
char *mnem;
{
if ( n_mnems == MAX_MNEMONICS)
error( "too many assembler instructions!! MAX_MNEMONICS = %d",
MAX_MNEMONICS);
else
mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
}
1988-01-07 16:09:30 +00:00
end_table()
1987-11-20 11:12:07 +00:00
1988-01-07 16:09:30 +00:00
/* Flush information in the array 'mnemonic'
*/
1987-11-20 11:12:07 +00:00
{
int i;
quicksort( 0, n_mnems - 1);
out( "char *mnemonic[] = {\n");
for ( i = 0; i < n_mnems - 1; i++)
out( "\t\"%s\",\n", mnemonic[i]);
out( "\t\"%s\"};\n\n", mnemonic[ n_mnems-1]);
out( "int (*instruction[])() = {\n");
for ( i = 0; i < n_mnems - 1; i++)
out( "\t%s_instr,\n", mnemonic[i]);
out( "\t%s_instr};\n\n", mnemonic[ n_mnems-1]);
out( "int n_mnems = %d;\n", n_mnems);
}
quicksort( lower, upper)
int lower, upper;
1988-01-07 16:09:30 +00:00
/* Sort the array 'mnemonic'.
1987-11-20 11:12:07 +00:00
*/
{
char *key, *tmp;
int index1, index2;
if ( lower >= upper)
return;
key = mnemonic[lower];
index1 = lower;
index2 = upper+1;
while ( index1 < index2) {
do
index1++;
while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
do
index2--;
while ( strcmp( mnemonic[index2], key) > 0);
if ( index1 < index2) {
tmp = mnemonic[index2];
mnemonic[index2] = mnemonic[index1];
mnemonic[index1] = tmp;
}
}
mnemonic[lower] = mnemonic[index2];
mnemonic[index2] = key;
quicksort( lower, index2-1);
quicksort( index2+1, upper);
}