6 extern error(char *, ...);
14 /* This file contains the routine assemble(). Assemble() cuts an
15 * assembly instruction in a label, a mnemonic and several operands.
16 * For a mnemonic,label and operands it calls table writer defined
17 * routines, process_mnemonic() * process_label() and process_operand(),
18 * to give the table writer the oppurtunity to do something special.
19 * At the end assemble() calls the routine belonging to the mnemonic
20 * with the supplied operands.
21 * If the table writer has other expectations of assemble() he should
22 * write his own version.
23 * Assemble parser the following instructions :
24 * INSTR ::= [ STRING ':']? [ STRING [ OPERAND ( ',' OPERAND)*]? ]?
25 * OPERAND ::= STRING [ '{' char* '}' |
28 * note : nested brackets are not recognized.
32 /* The following global varaibles are defined in the EM_parser.
35 extern char *mnemonic[];
36 extern int (*instruction[])(), n_mnems;
38 /* The struct t_operand must be defined by the table writer in "as.h".
39 * The constant MAX_OPERANDS is defined in "const.h"
40 * To change MAX_OPERANDS effectively, the last statement in
41 * execute_mnem() must be changed.
44 struct t_operand operand[ MAX_OPERANDS];
48 char *skip_space(), *parse_label(), *parse_mnemonic(), *parse_operand(),
49 *skip_string(), *match_ch(), *Salloc(), *skip_operand();
55 /* Break an assembly instruction down in a LABEL, MNEMONIC and OPERANDS.
58 char *ptr, *copy, *mnem;
61 copy = ptr = Salloc( instr, strlen( instr)+1);
63 ptr = skip_space( ptr);
64 if ( label( ptr)) { /* Look for a label */
65 ptr = parse_label( ptr);
66 if ( *ptr == '\0') return;
69 ptr = parse_mnemonic( ptr, &mnem);
70 while ( *ptr != '\0') { /* parse operans */
71 if ( n_ops++ == MAX_OPERANDS)
72 error( "to many operands\n");
73 ptr = parse_operand( ptr, n_ops, instr);
76 execute_mnemonic( mnem); /* Execute the assembler instruction */
84 ptr = skip_string( ptr);
85 ptr = skip_space( ptr);
90 char *parse_label( ptr)
95 ptr = skip_string( ptr);
100 ptr = skip_space( ptr);
101 ptr++; /* skip ':' */
104 ptr = skip_space( ptr);
109 char *parse_mnemonic( ptr, mnem)
113 ptr = skip_string( ptr);
116 ptr = skip_space( ptr);
122 char *parse_operand( ptr, n_ops, instr)
129 ptr = skip_operand( ptr, instr);
130 for( last=ptr-1; isspace( *last); last--)
133 ptr = skip_space( ptr + 1);
137 process_operand( op, &operand[ n_ops-1]);
142 char *skip_operand( ptr, instr)
145 while ( *ptr != ',' && *ptr != '\0') {
147 case '{' : ptr = match_ch( '}', ptr, instr);
149 case '(' : ptr = match_ch( ')', ptr, instr);
151 case '[' : ptr = match_ch( ']', ptr, instr);
160 char *match_ch( c, str, instr)
161 char c, *str, *instr;
163 char *ptr, *strindex();
165 ptr = strindex( str, c);
167 error( "syntax error in %s : %c expected\n", instr, c);
175 char *skip_string( ptr)
178 while ( *ptr != '\0' && !isspace( *ptr) && *ptr != ':')
184 char *skip_space( ptr)
187 while ( isspace( *ptr) )
193 /*** Execution **************************************************************/
196 execute_mnemonic( mnem)
199 /* Find the function by "mnem" and execute it.
202 int low, mid, high, rel;
204 process_mnemonic( mnem);
210 mid = ( low + high) / 2;
211 rel = strcmp(mnem, mnemonic[ mid]);
215 else if ( high == low) {
216 error( "can't find %s", mnem);
222 /* watch it, mid is truncated */
223 low = ( mid == low ? low + 1: mid);
225 ( *( instruction[ mid]))( &operand[0], &operand[1], &operand[2],
230 /*** Error ****************************************************************/
234 error(char *fmt, ...)
241 fprint( STDERR, "ERROR in line %d : ", yylineno);
242 doprnt( STDERR, fmt, args);
243 fprint( STDERR, "\n");
258 fmt = va_arg(args, char *);
259 fprint( STDERR, "ERROR in line %d : ", yylineno);
260 doprnt( STDERR, fmt, args);
261 fprint( STDERR, "\n");