ack/doc/em/int/mktables.c
1987-03-31 08:05:50 +00:00

235 lines
4.7 KiB
C

/* $Header$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
*/
/* Author: E.G. Keizer */
#include <stdio.h>
#include <util/ass/ip_spec.h>
#include <h/em_spec.h>
#include <h/em_flag.h>
/* This program reads the human readable interpreter specification
and produces a efficient machine representation that can be
translated by a C-compiler.
*/
#define ESCAP 256
int nerror = 0 ;
int atend = 0 ;
int line = 1 ;
int maxinsl= 0 ;
extern char em_mnem[][4] ;
char esca[] = "escape" ;
#define ename(no) ((no)==ESCAP?esca:em_mnem[(no)])
extern char em_flag[] ;
main(argc,argv) char **argv ; {
if ( argc>1 ) {
if ( freopen(argv[1],"r",stdin)==NULL) {
fatal("Cannot open %s",argv[1]) ;
}
}
if ( argc>2 ) {
if ( freopen(argv[2],"w",stdout)==NULL) {
fatal("Cannot create %s",argv[2]) ;
}
}
if ( argc>3 ) {
fatal("%s [ file [ file ] ]",argv[0]) ;
}
atend=0 ;
readin();
atend=1 ;
exit(nerror) ;
}
readin() {
char *ident();
char *firstid ;
int opcode,flags;
int c;
while ( !feof(stdin) ) {
firstid=ident() ;
if ( *firstid=='\n' || feof(stdin) ) continue ;
opcode = getmnem(firstid) ;
printf("%d ",opcode+1) ;
flags = decflag(ident(),opcode) ;
switch(em_flag[opcode]&EM_PAR) {
case PAR_D: case PAR_F: case PAR_B: case PAR_L: case PAR_C:
putchar('S') ;
}
putchar(' ');
while ( (c=readchar())!='\n' && c!=EOF ) putchar(c) ;
putchar('\n') ;
}
}
char *ident() {
/* skip spaces and tabs, anything up to space,tab or eof is
a identifier.
Anything from # to end-of-line is an end-of-line.
End-of-line is an identifier all by itself.
*/
static char array[200] ;
register int c ;
register char *cc ;
do {
c=readchar() ;
} while ( c==' ' || c=='\t' ) ;
for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) {
if ( c=='#' ) {
do {
c=readchar();
} while ( c!='\n' && c!=EOF ) ;
}
*cc = c ;
if ( c=='\n' && cc==array ) break ;
c=readchar() ;
if ( c=='\n' ) {
pushback(c) ;
break ;
}
if ( c==' ' || c=='\t' || c==EOF ) break ;
}
*++cc=0 ;
return array ;
}
int getmnem(str) char *str ; {
char (*ptr)[4] ;
for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem][0] ; ptr++ ) {
if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ;
}
error("Illegal mnemonic") ;
return 0 ;
}
error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
fprintf(stderr,"\n");
nerror++ ;
}
mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
fprintf(stderr,"\n");
}
fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
error(str,a1,a2,a3,a4,a5,a6) ;
exit(1) ;
}
#define ILLGL -1
check(val) int val ; {
if ( val!=ILLGL ) error("Illegal flag combination") ;
}
int decflag(str,opc) char *str ; {
int type ;
int escape ;
int range ;
int wordm ;
int notzero ;
char c;
type=escape=range=wordm=notzero= ILLGL ;
while ( c= *str++ ) {
switch ( c ) {
case 'm' :
check(type) ; type=OPMINI ; break ;
case 's' :
check(type) ; type=OPSHORT ; break ;
case '-' :
check(type) ; type=OPNO ;
if ( (em_flag[opc]&EM_PAR)==PAR_W ) c='i' ;
break ;
case '1' :
check(type) ; type=OP8 ; break ;
case '2' :
check(type) ; type=OP16 ; break ;
case '4' :
check(type) ; type=OP32 ; break ;
case '8' :
check(type) ; type=OP64 ; break ;
case 'e' :
check(escape) ; escape=0 ; break ;
case 'N' :
check(range) ; range= 2 ; break ;
case 'P' :
check(range) ; range= 1 ; break ;
case 'w' :
check(wordm) ; wordm=0 ; break ;
case 'o' :
check(notzero) ; notzero=0 ; break ;
default :
error("Unknown flag") ;
}
putchar(c);
}
if ( type==ILLGL ) error("Type must be specified") ;
switch ( type ) {
case OP64 :
case OP32 :
if ( escape!=ILLGL ) error("Conflicting escapes") ;
escape=ILLGL ;
case OP16 :
case OP8 :
case OPSHORT :
case OPNO :
if ( notzero!=ILLGL ) mess("Improbable OPNZ") ;
if ( type==OPNO && range!=ILLGL ) {
mess("No operand in range") ;
}
}
if ( escape!=ILLGL ) type|=OPESC ;
if ( wordm!=ILLGL ) type|=OPWORD ;
switch ( range) {
case ILLGL : type|=OP_BOTH ; break ;
case 1 : type|=OP_POS ; break ;
case 2 : type|=OP_NEG ; break ;
}
if ( notzero!=ILLGL ) type|=OPNZ ;
return type ;
}
static int pushchar ;
static int pushf ;
int readchar() {
int c ;
if ( pushf ) {
pushf=0 ;
c = pushchar ;
} else {
if ( feof(stdin) ) return EOF ;
c=getc(stdin) ;
}
if ( c=='\n' ) line++ ;
return c ;
}
pushback(c) {
if ( pushf ) {
fatal("Double pushback") ;
}
pushf++ ;
pushchar=c ;
if ( c=='\n' ) line-- ;
}