home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Copyright (c) 1988,1991 by Sozobon, Limited. Author: Joseph M Treat
- *
- * Permission is granted to anyone to use this software for any purpose
- * on any computer system, and to redistribute it freely, with the
- * following restrictions:
- * 1) No charge may be made other than reasonable charges for reproduction.
- * 2) Modified versions must be clearly marked as such.
- * 3) The authors are not responsible for any harmful consequences
- * of using this software, even if they result from defects in it.
- */
-
- #include "jas.h"
- #include "scan.h"
- #include "parse.h"
-
- FILE *yyin;
- int lastc = 0;
- int ateof = 0;
- int do_star = 1;
-
- #ifdef MINIX
- /*
- * this table is used to keep track of 'number' lables and references
- * to them; e.g. bra 4f, bge 3b, etc
- */
-
- static int back_labs[10] = { 0 };
- static int forw_labs[10] = { 0 };
- static int lab_no = 101;
-
- #endif
-
- getnext()
- {
- static char buf[80];
- static int cnt = 0, size = 0;
- static last = '\n';
- int sawstar = 0;
- extern char *fgets();
-
- do {
- while ( cnt >= size ) {
- if ( fgets( buf, 80, yyin ) == (char *) NULL ) {
- return EOF;
- }
- size = strlen( buf );
- cnt = 0;
- if ( do_star && last == '\n' ) {
- while ( buf[cnt] &&
- (buf[cnt]==' '||buf[cnt]=='\t'))
- cnt++;
- if ( sawstar || buf[cnt] == '*' ) {
- sawstar = 1;
- while ( buf[cnt] && buf[cnt] != '\n' )
- cnt++;
- }
- }
- }
- if (sawstar || (do_star && buf[cnt]=='\t' && buf[cnt+1]=='*')) {
- sawstar = 1;
- while ( buf[cnt] && buf[cnt] != '\n' )
- cnt++;
- }
- } while ( ! buf[cnt] );
- return last = buf[cnt++];
- }
-
- yygetc()
- {
- register int c;
-
- if ( ateof )
- return 0;
- if ( lastc ) {
- c = lastc;
- lastc = 0;
- } else
- c = getnext();
- if ( c && c != EOF ) {
- return c;
- }
- ateof = 1;
- return 0;
- }
-
- yyungetc( c )
- int c;
- {
- if ( lastc ) {
- char buf[32];
- extern int line;
-
- sprintf( buf, "%c & %c pushed back!!", lastc, c );
- error( line, buf );
- }
- lastc = c;
- }
-
- yylex()
- {
- register int i;
- int c;
- struct lexacts *lp;
- char buf[16];
- extern YYSTYPE yylval;
- extern int nwords;
- extern struct lexacts actions[];
- extern struct reserved words[];
- extern INST *ifind();
- extern SYM *lookup();
-
- for ( c = yygetc(); c; c = yygetc() ) {
- lp = &actions[c];
- if ( lp->acts & L_EXTRA ) {
- i = yyprocess( c );
- if ( i == COMMENT )
- continue;
- else if ( i )
- return i;
- }
- if ( lp->acts & L_TOKEN ) {
- return lp->retval;
- }
- if ( lp->acts & L_BEGID ) {
- int tsz;
- char *nm, *tnm;
- extern yywidth;
-
- tsz = 16;
- nm = ALLOC(tsz,char);
- for (i = 0; c && (actions[c].acts & L_MIDID); ) {
- if ( i+2 > tsz ) {
- tsz += 16;
- nm = REALLO(nm,tsz,char);
- }
- nm[i++] = c;
- c = yygetc();
- }
- nm[i] = '\0';
- if ( c )
- yyungetc( c );
- tnm = STRCPY(nm);
- yymodify( tnm );
- yywidth = 0;
-
- tsz = strlen( tnm );
- if ( tsz >= 2 && tnm[tsz-2] == '.' ) {
- switch ( tnm[tsz-1] ) {
- case 'b':
- yywidth = 8;
- nm[tsz-2] = tnm[tsz-2] = '\0';
- break;
- case 'w':
- yywidth = 16;
- nm[tsz-2] = tnm[tsz-2] = '\0';
- break;
- case 'l':
- yywidth = 32;
- nm[tsz-2] = tnm[tsz-2] = '\0';
- break;
- }
- }
-
- {
- register int lo = 0;
- register int hi = nwords-2;
- register int d;
- register struct reserved *rp;
-
- while ( lo <= hi ) {
- i = (lo + hi) / 2;
- rp = &words[i];
- d = strcmp( tnm, rp->name );
- if (! strcmp( tnm, rp->name ) ) {
- yylval.val = rp->value;
- #ifdef MINIX
- if ( rp->token == _DC || rp->token == _DS ) {
- if ( rp->value )
- yywidth = rp->value;
- }
- #endif
- return rp->token;
- } else if ( d < 0 ) {
- hi = i-1;
- } else if ( d > 0 ) {
- lo = i+1;
- } else { /* wrong scope */
- break;
- }
- }
- }
-
- /*
- * if it's not a reserved word, put the length back
- */
- if ( yywidth != 0 )
- nm[tsz-2] = tnm[tsz-2] = '.';
-
- {
- register STMT *sp;
- register INST *ip;
- short misc;
-
- ip = ifind( tnm, &misc );
- if ( ip != (INST *) NULL ) {
- sp = ALLO(STMT);
- sp->inst = ip;
- sp->misc = misc;
- yylval.stmt = sp;
- return INSTR;
- }
- }
-
- /*
- * if it's not a mnemonic, take the length away
- */
- if ( yywidth != 0 )
- nm[tsz-2] = '\0';
-
- yylval.sym = lookup( nm );
- free( tnm );
- free( nm );
- return lp->retval;
- }
- if ( lp->acts & L_DIGIT ) {
- extern long getnum();
-
- #ifdef MINIX
- if ( c >= '0' && c <= '9' ) {
- int k;
- char lbuf[16];
-
- k = yygetc();
- switch ( k ) {
- case ':':
- yyungetc( ':' );
- k = c - '0';
- if ( forw_labs[k] ) {
- back_labs[k] = forw_labs[k];
- forw_labs[k] = 0;
- } else {
- back_labs[k] = lab_no++;
- }
- sprintf( lbuf, "L#%d", back_labs[k] );
- yylval.sym = lookup( lbuf );
- return NAME;
- case 'f':
- k = c - '0';
- if (! forw_labs[k] ) {
- forw_labs[k] = lab_no++;
- }
- sprintf( lbuf, "L#%d", forw_labs[k] );
- yylval.sym = lookup( lbuf );
- return NAME;
- case 'b':
- k = c - '0';
- if (! back_labs[k] ) {
- Yerror( "back reference to unknown numbered label" );
- }
- sprintf( lbuf, "L#%d", back_labs[k] );
- yylval.sym = lookup( lbuf );
- return NAME;
- default:
- yyungetc( k );
- break;
- }
- }
- #endif
- for (i = 0; c && (actions[c].acts & L_DIGIT); i++) {
- buf[i] = c;
- c = yygetc();
- }
- buf[i] = '\0';
- if ( c )
- yyungetc( c );
- yylval.val = getnum( buf );
- return lp->retval;
- }
- /* L_SKIP */
- }
- return 0;
- }
-
- long
- getnum( s )
- register char *s;
- {
- register long val;
- register int base;
-
- switch ( *s ) {
- case '$':
- base = 16;
- s++;
- break;
- case '0':
- #ifdef MINIX
- if ( s[1] == 'x' ) {
- s += 2;
- base = 16;
- break;
- }
- #endif
- case '@':
- base = 8;
- s++;
- break;
- default:
- base = 10;
- break;
- }
-
- for ( val = 0L; *s; s++ ) {
- if ( *s >= '0' && *s <= '7' ) {
- val = val * base + ( *s - '0' );
- } else if ( *s >= '8' && *s <= '9' ) {
- if ( base == 8 )
- Yerror( "invalid octal constant" );
- val = val * base + ( *s - '0' );
- } else if ( *s >= 'a' && *s <= 'f' ) {
- if ( base == 8 )
- Yerror( "invalid octal constant" );
- if ( base == 10 )
- Yerror( "invalid decimal constant" );
- val = val * base + ( *s - 'a' + 10 );
- } else /* if ( *s >= 'A' && *s <= 'F' ) */ {
- if ( base == 8 )
- Yerror( "invalid octal constant" );
- if ( base == 10 )
- Yerror( "invalid decimal constant" );
- val = val * base + ( *s - 'A' + 10 );
- }
-
- }
- return val;
- }
-