237 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
	
		
			4.8 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 <ip_spec.h>
 | |
| #include <em_spec.h>
 | |
| #include <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 'u' :
 | |
| 			check(type) ; type=OP16U ; 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 OP16U :
 | |
| 	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-- ;
 | |
| }
 |