home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / sozo2 / scsrc20.lzh / JAS.LZH / SCAN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-22  |  6.6 KB  |  339 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15. #include "scan.h"
  16. #include "parse.h"
  17.  
  18. FILE *yyin;
  19. int lastc = 0;
  20. int ateof = 0;
  21. int do_star = 1;
  22.  
  23. #ifdef MINIX
  24.     /*
  25.      * this table is used to keep track of 'number' lables and references
  26.      * to them; e.g. bra 4f, bge 3b, etc
  27.      */
  28.  
  29. static int back_labs[10] = { 0 };
  30. static int forw_labs[10] = { 0 };
  31. static int lab_no = 101;
  32.  
  33. #endif
  34.  
  35. getnext()
  36. {
  37.     static char buf[80];
  38.     static int cnt = 0, size = 0;
  39.     static last = '\n';
  40.     int sawstar = 0;
  41.     extern char *fgets();
  42.  
  43.     do {
  44.         while ( cnt >= size ) {
  45.             if ( fgets( buf, 80, yyin ) == (char *) NULL ) {
  46.                 return EOF;
  47.             }
  48.             size = strlen( buf );
  49.             cnt = 0;
  50.             if ( do_star && last == '\n' ) {
  51.                 while ( buf[cnt] &&
  52.                         (buf[cnt]==' '||buf[cnt]=='\t'))
  53.                     cnt++;
  54.                 if ( sawstar || buf[cnt] == '*' ) {
  55.                     sawstar = 1;
  56.                     while ( buf[cnt] && buf[cnt] != '\n' )
  57.                         cnt++;
  58.                 }
  59.             }
  60.         }
  61.         if (sawstar || (do_star && buf[cnt]=='\t' && buf[cnt+1]=='*')) {
  62.             sawstar = 1;
  63.             while ( buf[cnt] && buf[cnt] != '\n' )
  64.                 cnt++;
  65.         }
  66.     } while ( ! buf[cnt] );
  67.     return last = buf[cnt++];
  68. }
  69.  
  70. yygetc()
  71. {
  72.     register int c;
  73.  
  74.     if ( ateof )
  75.         return 0;
  76.     if ( lastc ) {
  77.         c = lastc;
  78.         lastc = 0;
  79.     } else
  80.         c = getnext();
  81.     if ( c && c != EOF ) {
  82.         return c;
  83.     }
  84.     ateof = 1;
  85.     return 0;
  86. }
  87.  
  88. yyungetc( c )
  89.     int c;
  90. {
  91.     if ( lastc ) {
  92.         char buf[32];
  93.         extern int line;
  94.  
  95.         sprintf( buf, "%c & %c pushed back!!", lastc, c );
  96.         error( line, buf );
  97.     }
  98.     lastc = c;
  99. }
  100.  
  101. yylex()
  102. {
  103.     register int i;
  104.     int c;
  105.     struct lexacts *lp;
  106.     char buf[16];
  107.     extern YYSTYPE yylval;
  108.     extern int nwords;
  109.     extern struct lexacts actions[];
  110.     extern struct reserved words[];
  111.     extern INST *ifind();
  112.     extern SYM *lookup();
  113.  
  114.     for ( c = yygetc(); c; c = yygetc() ) {
  115.         lp = &actions[c];
  116.         if ( lp->acts & L_EXTRA ) {
  117.             i = yyprocess( c );
  118.             if ( i == COMMENT )
  119.                 continue;
  120.             else if ( i )
  121.                 return i;
  122.         }
  123.         if ( lp->acts & L_TOKEN ) {
  124.             return lp->retval;
  125.         }
  126.         if ( lp->acts & L_BEGID ) {
  127.             int tsz;
  128.             char *nm, *tnm;
  129.             extern yywidth;
  130.  
  131.             tsz = 16;
  132.             nm = ALLOC(tsz,char);
  133.             for (i = 0; c && (actions[c].acts & L_MIDID); ) {
  134.                 if ( i+2 > tsz ) {
  135.                     tsz += 16;
  136.                     nm = REALLO(nm,tsz,char);
  137.                 }
  138.                 nm[i++] = c;
  139.                 c = yygetc();
  140.             }
  141.             nm[i] = '\0';
  142.             if ( c )
  143.                 yyungetc( c );
  144.             tnm = STRCPY(nm);
  145.             yymodify( tnm );
  146.             yywidth = 0;
  147.  
  148.             tsz = strlen( tnm );
  149.             if ( tsz >= 2 && tnm[tsz-2] == '.' ) {
  150.                 switch ( tnm[tsz-1] ) {
  151.                 case 'b':
  152.                     yywidth = 8;
  153.                     nm[tsz-2] = tnm[tsz-2] = '\0';
  154.                     break;
  155.                 case 'w':
  156.                     yywidth = 16;
  157.                     nm[tsz-2] = tnm[tsz-2] = '\0';
  158.                     break;
  159.                 case 'l':
  160.                     yywidth = 32;
  161.                     nm[tsz-2] = tnm[tsz-2] = '\0';
  162.                     break;
  163.                 }
  164.             }
  165.             
  166.             {
  167.                 register int lo = 0;
  168.                 register int hi = nwords-2;
  169.                 register int d;
  170.                 register struct reserved *rp;
  171.  
  172.                 while ( lo <= hi ) {
  173.                     i = (lo + hi) / 2;
  174.                     rp = &words[i];
  175.                     d = strcmp( tnm, rp->name );
  176.                     if (! strcmp( tnm, rp->name ) ) {
  177.                         yylval.val = rp->value;
  178. #ifdef MINIX
  179.                         if ( rp->token == _DC || rp->token == _DS )  {
  180.                             if ( rp->value )
  181.                                 yywidth = rp->value;
  182.                         }
  183. #endif
  184.                         return rp->token;
  185.                     } else if ( d < 0 ) {
  186.                         hi = i-1;
  187.                     } else if ( d > 0 ) {
  188.                         lo = i+1;
  189.                     } else { /* wrong scope */
  190.                         break;
  191.                     }
  192.                 }
  193.             }
  194.             
  195.             /*
  196.              * if it's not a reserved word, put the length back
  197.              */
  198.             if ( yywidth != 0 )
  199.                 nm[tsz-2] = tnm[tsz-2] = '.';
  200.  
  201.             {
  202.                 register STMT *sp;
  203.                 register INST *ip;
  204.                 short misc;
  205.  
  206.                 ip = ifind( tnm, &misc );
  207.                 if ( ip != (INST *) NULL ) {
  208.                     sp = ALLO(STMT);
  209.                     sp->inst = ip;
  210.                     sp->misc = misc;
  211.                     yylval.stmt = sp; 
  212.                     return INSTR;
  213.                 }
  214.             }
  215.  
  216.             /*
  217.              * if it's not a mnemonic, take the length away
  218.              */
  219.             if ( yywidth != 0 )
  220.                 nm[tsz-2] = '\0';
  221.  
  222.             yylval.sym = lookup( nm );
  223.             free( tnm );
  224.             free( nm );
  225.             return lp->retval;
  226.         }
  227.         if ( lp->acts & L_DIGIT ) {
  228.             extern long getnum();
  229.  
  230. #ifdef MINIX
  231.             if ( c >= '0' && c <= '9' ) {
  232.                 int k;
  233.                 char lbuf[16];
  234.  
  235.                 k = yygetc();
  236.                 switch ( k ) {
  237.                 case ':':
  238.                     yyungetc( ':' );
  239.                     k = c - '0';
  240.                     if ( forw_labs[k] ) {
  241.                         back_labs[k] = forw_labs[k];
  242.                         forw_labs[k] = 0;
  243.                     } else {
  244.                         back_labs[k] = lab_no++;
  245.                     }
  246.                     sprintf( lbuf, "L#%d", back_labs[k] );
  247.                     yylval.sym = lookup( lbuf );
  248.                     return NAME;
  249.                 case 'f':
  250.                     k = c - '0';
  251.                     if (! forw_labs[k] ) {
  252.                         forw_labs[k] = lab_no++;
  253.                     }
  254.                     sprintf( lbuf, "L#%d", forw_labs[k] );
  255.                     yylval.sym = lookup( lbuf );
  256.                     return NAME;
  257.                 case 'b':
  258.                     k = c - '0';
  259.                     if (! back_labs[k] ) {
  260.                         Yerror( "back reference to unknown numbered label" );
  261.                     }
  262.                     sprintf( lbuf, "L#%d", back_labs[k] );
  263.                     yylval.sym = lookup( lbuf );
  264.                     return NAME;
  265.                 default:
  266.                     yyungetc( k );
  267.                     break;
  268.                 }
  269.             }
  270. #endif
  271.             for (i = 0; c && (actions[c].acts & L_DIGIT); i++) {
  272.                 buf[i] = c;
  273.                 c = yygetc();
  274.             }
  275.             buf[i] = '\0';
  276.             if ( c )
  277.                 yyungetc( c );
  278.             yylval.val = getnum( buf );
  279.             return lp->retval;
  280.         }
  281.         /* L_SKIP */
  282.     }
  283.     return 0;
  284. }
  285.  
  286. long
  287. getnum( s )
  288.     register char *s;
  289. {
  290.     register long val;
  291.     register int base;
  292.  
  293.     switch ( *s ) {
  294.     case '$':
  295.         base = 16;
  296.         s++;
  297.         break;
  298.     case '0':
  299. #ifdef MINIX
  300.         if ( s[1] == 'x' ) {
  301.             s += 2;
  302.             base = 16;
  303.             break;
  304.         }
  305. #endif
  306.     case '@':
  307.         base = 8;
  308.         s++;
  309.         break;
  310.     default:
  311.         base = 10;
  312.         break;
  313.     }
  314.  
  315.     for ( val = 0L; *s; s++ ) {
  316.         if ( *s >= '0' && *s <= '7' ) {
  317.             val = val * base + ( *s - '0' );
  318.         } else if ( *s >= '8' && *s <= '9' ) {
  319.             if ( base == 8 )
  320.                 Yerror( "invalid octal constant" );
  321.             val = val * base + ( *s - '0' );
  322.         } else if ( *s >= 'a' && *s <= 'f' ) {
  323.             if ( base == 8 )
  324.                 Yerror( "invalid octal constant" );
  325.             if ( base == 10 )
  326.                 Yerror( "invalid decimal constant" );
  327.             val = val * base + ( *s - 'a' + 10 );
  328.         } else /* if ( *s >= 'A' && *s <= 'F' ) */ {
  329.             if ( base == 8 )
  330.                 Yerror( "invalid octal constant" );
  331.             if ( base == 10 )
  332.                 Yerror( "invalid decimal constant" );
  333.             val = val * base + ( *s - 'A' + 10 );
  334.         }
  335.  
  336.     }
  337.     return val;
  338. }
  339.