BSD 4 release
[unix-history] / usr / src / cmd / as / asscan.c
index ee3fd8c..6ba09c6 100644 (file)
@@ -1,20 +1,56 @@
-/* Copyright (c) 1979 Regents of the University of California */
+/* Copyright (c) 1980 Regents of the University of California */
+static char sccsid[] = "@(#)asscan.c 4.6 9/8/80";
 #include <stdio.h>
 #include "as.h"
 #include "asscan.h"
 
 #include <stdio.h>
 #include "as.h"
 #include "asscan.h"
 
-extern int     d124;
-extern         struct  exp     *xp;
-
-struct tokbufdesc *bufstart;           /*where the buffer list begins*/
-struct tokbufdesc *buftail;            /*last one on the list*/
-struct tokbufdesc *emptybuf;           /*the one being filled*/
+/*
+ *     NOTE:
+ *             This version of the assembler does not use fread and fwrite
+ *     for the token buffering.  The token buffers are integrals of BUFSIZ
+ *     at all times, so we use direct read and write.  fread and fwrite
+ *     as supplied from BTL in stdio are HORRENDOUSLY inefficient,
+ *     as they use putchar for each character, nested two deep in loops.
+ */
+#define writeTEST(pointer, size, nelements, ioptr) \
+       write(ioptr->_file, pointer, nelements * size) != nelements * size
 
 
+#define readTEST(pointer, size, nelements, ioptr) \
+       read(ioptr->_file, pointer, nelements * size) != nelements * size
+/*
+ *     Variables to manage the token buffering.
+ *     We scan (lexically analyze) a large number of tokens, and
+ *     then parse all of the tokens in the scan buffer.
+ *     This reduces procedure call overhead when the parser
+ *     demands a token, allows for an efficient reread during
+ *     the second pass, and confuses the line number reporting
+ *     for errors encountered in the scanner and in the parser.
+ */
 #define TOKDALLOP      8
 #define TOKDALLOP      8
+struct tokbufdesc *bufstart;   /*where the buffer list begins*/
+struct tokbufdesc *buftail;    /*last one on the list*/
+struct tokbufdesc *emptybuf;   /*the one being filled*/
+/*
+ *     If we are using VM, during the second pass we reclaim the used
+ *     token buffers for saving the relocation information
+ */
+struct tokbufdesc *tok_free;   /* free pool */
+struct tokbufdesc *tok_temp;   /* temporary for doing list manipulation */
+/*
+ *     Other token buffer managers
+ */
+int    bufno;                  /*which buffer number: 0,1 for tmp file*/
+struct         tokbufdesc tokbuf[2];   /*our initial increment of buffers*/
+ptrall tokptr;                 /*where the current token comes from*/
+ptrall tokub;                  /*the last token in the current token buffer*/
 
 
-int    useVM;                          /*keep `tmp' file in virtual memory*/
-int    bufno;                          /*which buffer number: 0,1 for tmp file*/
-struct         tokbufdesc tokbuf[2];           /*our initial increment of buffers*/
+/*
+ *     Variables to manage the string buffering
+ *     declared in asscan.h.
+ */
+int    strno;                  /*the current string being filled*/
+struct strdesc strbuf[3];      /*the string buffers; the first for nulls*/
+struct strdesc *strptr;        /*current string buffer being filled*/
        
 inittmpfile()
 {
        
 inittmpfile()
 {
@@ -28,6 +64,8 @@ inittmpfile()
                tokbuf[0].tok_count = -1;
                tokbuf[1].tok_count = -1;
        }
                tokbuf[0].tok_count = -1;
                tokbuf[1].tok_count = -1;
        }
+       tok_temp = 0;
+       tok_free = 0;
        bufno = 0;
        emptybuf = &tokbuf[bufno];
        tokptr = 0;
        bufno = 0;
        emptybuf = &tokbuf[bufno];
        tokptr = 0;
@@ -45,7 +83,7 @@ closetmpfile()
                         *      written out yet
                         */
                        if (tokbuf[bufno ^ 1].tok_count >= 0){
                         *      written out yet
                         */
                        if (tokbuf[bufno ^ 1].tok_count >= 0){
-                               if (fwrite(&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tmpfil) != 1){
+                               if (writeTEST((char *)&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tmpfil)){
                                  badwrite:
                                        yyerror("Unexpected end of file writing the interpass tmp file");
                                exit(2);
                                  badwrite:
                                        yyerror("Unexpected end of file writing the interpass tmp file");
                                exit(2);
@@ -57,8 +95,8 @@ closetmpfile()
                         *      in the argument list
                         */
                        tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
                         *      in the argument list
                         */
                        tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
-                       if (fwrite(&tokbuf[bufno], sizeof *emptybuf, 1, tmpfil)
-                                       != 1) goto      badwrite;
+                       if (writeTEST((char *)&tokbuf[bufno], sizeof *emptybuf, 1, tmpfil))
+                               goto badwrite;
                }
        }       /*end of being pass 1*/
 }
                }
        }       /*end of being pass 1*/
 }
@@ -87,9 +125,10 @@ closetmpfile()
 
 #ifdef DEBUG
        ptrall  firsttoken;
 
 #ifdef DEBUG
        ptrall  firsttoken;
-#endif
+#endif DEBUG
 
 extern int             yylval;         /*global communication with parser*/
 
 extern int             yylval;         /*global communication with parser*/
+static int             Lastjxxx;       /*this ONLY shuts up cc; see below*/
 
 toktype yylex()
 {
 
 toktype yylex()
 {
@@ -102,171 +141,182 @@ toktype yylex()
        if (bufptr < tokub){
                gtoken(val, bufptr);
                switch(yylval = val){
        if (bufptr < tokub){
                gtoken(val, bufptr);
                switch(yylval = val){
-                       case    PARSEEOF :
-                                       yylval = val = PARSEEOF;
-                                       break;
-                       case    INT:
-                                       locxp = xp++;
-                                       glong(locxp->xvalue, bufptr);
-                                 makevalue:
-                                       locxp->xtype = XABS;
-                                       locxp->xloc = 0;
-                                       locxp->xname = NULL;
-                                       yylval = (int)locxp;
-                                       break;
-                       case    FLTNUM: /*case patched on 3-Jan-80*/
-                                       locxp = xp++;
-                                       gdouble(locxp->doubval.dvalue, bufptr);
-                                       /*
-                                        *      We make sure that locxp->xvalue
-                                        *      is not in the range suitable for
-                                        *      a short literal.  The field
-                                        *      xvalue is only used for
-                                        *      integers, not doubles, but when
-                                        *      we test for short literals
-                                        *      in ascode.c, we look
-                                        *      at the field xvalue when
-                                        *      it encounters an in line
-                                        *      floating number. Ergo,
-                                        *      give it a bad value.
-                                        */
-                                       locxp->xvalue = -1;
-                                       goto makevalue;
-                       case    NAME:
-                                       gptr(yylval, bufptr);
-                                       lastnam = (struct symtab *)yylval;
-                                       break;
-                       case    SIZESPEC:
-                       case    REG:
-                       case    INSTn:
-                       case    INST0:
-                                       gchar(yylval, bufptr);
-                                       break;
-                       case    IJXXX:
-                                       gchar(yylval, bufptr);
-                                       gptr(lastjxxx, bufptr);
-                                       break;
-                       case    ILINESKIP:
-                                       gint(yylval, bufptr);
-                                       lineno += yylval;
-                                       goto top;
-                       case    SKIP:   
-                                       eatskiplg(bufptr);
-                                       goto top;
-                       case    VOID:   
-                                       goto top;
-                       case    STRING:
-                                       strptr = &strbuf[strno ^= 1];
-                                       strptr->str_lg = *((lgtype *)bufptr);
-                                       movestr(&strptr->str[0],
-                                               (char *)bufptr + sizeof(lgtype),
-                                               strptr->str_lg);
-                                       eatstrlg(bufptr);
-                                       yylval = (int)strptr;
-                                       break;
-                       case    ISTAB:
-                       case    ISTABSTR:
-                       case    ISTABNONE:
-                       case    ISTABDOT:
-                       case    IALIGN:
-                                       gptr(yylval, bufptr);
-                                       break;
-               } /*end of the switch*/
-
+               case    PARSEEOF :
+                               yylval = val = PARSEEOF;
+                               break;
+               case    BFINT:
+               case    INT:
+                               if (xp >= &explist[NEXP])
+                                    yyerror("Too many expressions; try simplyfing");
+                               else
+                                   locxp = xp++;
+                               glong(locxp->e_xvalue, bufptr);
+                               locxp->e_yvalue = 0;
+                         makevalue:
+                               locxp->e_xtype = XABS;
+                               locxp->e_xloc = 0;
+                               locxp->e_xname = NULL;
+                               yylval = (int)locxp;
+                               break;
+               case    FLTNUM: 
+                               if (xp >= &explist[NEXP])
+                                    yyerror("Too many expressions; try simplyfing");
+                               else
+                                   locxp = xp++;
+                               gdouble( ( (union Double *)locxp)->dvalue, bufptr);
+                               goto makevalue;
+               case    QUAD:
+                               if (xp >= &explist[NEXP])
+                                    yyerror("Too many expressions; try simplyfing");
+                               else
+                                   locxp = xp++;
+                               glong(locxp->e_xvalue, bufptr);
+                               glong(locxp->e_yvalue, bufptr);
+                               yylval = val = INT;
+                               goto makevalue;
+               case    NAME:
+                               gptr(yylval, bufptr);
+                               lastnam = (struct symtab *)yylval;
+                               break;
+               case    SIZESPEC:
+               case    REG:
+               case    INSTn:
+               case    INST0:
+                               gchar(yylval, bufptr);
+                               break;
+               case    IJXXX:
+                               gchar(yylval, bufptr);
+                               /* We can't cast Lastjxxx into (int *) here.. */
+                               gptr(Lastjxxx, bufptr);
+                               lastjxxx = (struct symtab *)Lastjxxx;
+                               break;
+               case    ILINESKIP:
+                               gint(yylval, bufptr);
+                               lineno += yylval;
+                               goto top;
+               case    SKIP:   
+                               eatskiplg(bufptr);
+                               goto top;
+               case    VOID:   
+                               goto top;
+               case    STRING:
+                               strptr = &strbuf[strno ^= 1];
+                               strptr->str_lg = *((lgtype *)bufptr);
+                               movestr(&strptr->str[0],
+                                       (char *)bufptr + sizeof(lgtype),
+                                       strptr->str_lg);
+                               eatstrlg(bufptr);
+                               yylval = (int)strptr;
+                               break;
+               case    ISTAB:
+               case    ISTABSTR:
+               case    ISTABNONE:
+               case    ISTABDOT:
+               case    IALIGN:
+                               gptr(yylval, bufptr);
+                               break;
+               } 
 #ifdef DEBUG
 #ifdef DEBUG
-
-               if (toktrace)
+               if (toktrace){
+               char    *tok_to_name();
+               printf("P: %d T#: %4d, %s ",
+                       passno, bufptr -  firsttoken, tok_to_name(val));
                switch(val){
                switch(val){
-                       case    INT:    printf("Class integer val %d\n",
-                                               ((struct exp *)yylval)->xvalue);
-                                       break;
-                       case    FLTNUM: printf("Class floating point num value %4.3f\n",
-                                       ((struct exp *)yylval) -> doubval.dvalue);
-                                       break;
-                       case    NAME:   printf("Class name, \"%.8s\"\n",
-                                               ((struct symtab *)yylval)->name);
-                                       break;
-                       case    REG:    printf("Class register, number %d\n",
-                                               yylval);
-                                       break;
-                       case    INSTn:  printf("Class INSTn, %.8s\n",
-                                               itab[0xFF &yylval]->name);
-                                       break;
-                       case    IJXXX:  printf("Class IJXXX, %.8s\n",
-                                               itab[0xFF &yylval]->name);
-                                       break;
-                       case    INST0:  printf("Class INST0, %.8s\n",
-                                               itab[0xFF &yylval]->name);
-                                       break;
-                       case    STRING: printf("Class string, length %d\n",
-                                               ((struct strdesc *)yylval)->str_lg);
-                                       break;
-                       default:        printf("Pass: %d Tok: %d Other class: %d, 0%o, '%c'\n",
-                                               passno,
-                                               bufptr -  firsttoken,
-                                               val,val, val);
-                                       break;
-               }               /*end of the debug switch*/
-#endif
+               case    INT:    printf("val %d",
+                                       ((struct exp *)yylval)->e_xvalue);
+                               break;
+               case    BFINT:  printf("val %d",
+                                       ((struct exp *)yylval)->e_xvalue);
+                               break;
+               case    QUAD:   printf("val[msd] = 0x%x, val[lsd] = 0x%x.",
+                               ((struct exp *)yylval)->e_xvalue,
+                               ((struct exp *)yylval)->e_yvalue);
+                               break;
+               case    FLTNUM: printf("value %20.17f",
+                               ((union Double *)yylval)->dvalue);
+                               break;
+               case    NAME:   printf("\"%.8s\"",
+                                       ((struct symtab *)yylval)->s_name);
+                               break;
+               case    REG:    printf(" r%d",
+                                       yylval);
+                               break;
+               case    IJXXX:
+               case    INST0:  
+               case    INSTn:  printf("%.8s",
+                                       itab[0xFF &yylval]->s_name);
+                               break;
+               case    STRING: printf("length %d ",
+                                       ((struct strdesc *)yylval)->str_lg);
+                               printf("value\"%s\"",
+                                       ((struct strdesc *)yylval)->str);
+                               break;
+               }               /*end of the debug switch*/
+               printf("\n");
+               }
+#endif DEBUG
 
 
-       }       /*end of this buffer*/
-       else {
-               if (useVM){
-                       bufno += 1;
+       } else {        /* start a new buffer */
+           if (useVM){
+               if (passno == 2){
+                       tok_temp = emptybuf->tok_next;
+                       emptybuf->tok_next = tok_free;
+                       tok_free = emptybuf;
+                       emptybuf = tok_temp;
+               } else {
                        emptybuf = emptybuf->tok_next;
                        emptybuf = emptybuf->tok_next;
-                       if (emptybuf == 0){
-                               struct  tokbufdesc *newdallop;
-                               int     i;
-                               if (passno == 2)
-                                       goto badread;
-                               emptybuf = newdallop = 
-                                 (struct tokbufdesc *)sbrk(
-                                       TOKDALLOP*sizeof (struct tokbufdesc));
-                               if (emptybuf == (struct tokbufdesc *)-1)
-                                       goto badwrite;
-                               for (i=0; i < TOKDALLOP; i++){
-                                       buftail->tok_next = newdallop;
-                                       buftail = newdallop;
-                                       newdallop += 1;
-                               }
-                               buftail->tok_next = 0;
-                       }       /*end of need to get more buffers*/
-                       (toktype *)bufptr = &(emptybuf->toks[0]);
-                       if (passno == 1)
-                               scan_dot_s(emptybuf);
-               } else {        /*don't use VM*/
-                       bufno ^= 1;
-                       emptybuf = &tokbuf[bufno];
-                       ((toktype *)bufptr) = &(emptybuf->toks[0]);
-                       if (passno == 1){
-                               /*
-                                *      First check if there are things to write
-                                *      out at all
-                                */
-                               if (emptybuf->tok_count >= 0){
-                                       if (fwrite(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){
-                                         badwrite:
-                                               yyerror("Unexpected end of file writing the interpass tmp file");
-                                               exit(2);
-                                       }
-                               }
-                               scan_dot_s(emptybuf);
-                       } else {        /*pass 2*/
-                               if (fread(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){
-                                 badread:
-                                       yyerror("Unexpected end of file while reading the interpass tmp file");
-                                       exit(1);
-                               }
-                       }       /*end of pass2*/
-               }       /*end of using a real live file*/
-               (char *)tokub = (char *)bufptr + emptybuf->tok_count;
+               }
+               bufno += 1;
+               if (emptybuf == 0){
+                       struct  tokbufdesc *newdallop;
+                       int     i;
+                       if (passno == 2)
+                               goto badread;
+                       emptybuf = newdallop = (struct tokbufdesc *)
+                         Calloc(TOKDALLOP, sizeof (struct tokbufdesc));
+                       for (i=0; i < TOKDALLOP; i++){
+                               buftail->tok_next = newdallop;
+                               buftail = newdallop;
+                               newdallop += 1;
+                       }
+                       buftail->tok_next = 0;
+               }       /*end of need to get more buffers*/
+               (toktype *)bufptr = &(emptybuf->toks[0]);
+               if (passno == 1)
+                       scan_dot_s(emptybuf);
+           } else {    /*don't use VM*/
+               bufno ^= 1;
+               emptybuf = &tokbuf[bufno];
+               ((toktype *)bufptr) = &(emptybuf->toks[0]);
+               if (passno == 1){
+                       /*
+                        *      First check if there are things to write
+                        *      out at all
+                        */
+                       if (emptybuf->tok_count >= 0){
+                           if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tmpfil)){
+                             badwrite:
+                               yyerror("Unexpected end of file writing the interpass tmp file");
+                               exit(2);
+                           }
+                       }
+                       scan_dot_s(emptybuf);
+               } else {        /*pass 2*/
+                   if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tmpfil)){
+                        badread:
+                            yyerror("Unexpected end of file while reading the interpass tmp file");
+                            exit(1);
+                   }
+               }
+           }   /*end of using a real live file*/
+           (char *)tokub = (char *)bufptr + emptybuf->tok_count;
 #ifdef DEBUG
 #ifdef DEBUG
-               firsttoken = bufptr;
-               if (debug)
-                       printf("created buffernumber %d with %d tokens\n",
-                               bufno, emptybuf->tok_count);
-#endif
-                       goto top;
+           firsttoken = bufptr;
+           if (debug)
+               printf("created buffernumber %d with %d tokens\n",
+                       bufno, emptybuf->tok_count);
+#endif DEBUG
+           goto top;
        }       /*end of reading/creating a new buffer*/
        tokptr = bufptr;                /*copy back the global value*/
        return(val);
        }       /*end of reading/creating a new buffer*/
        tokptr = bufptr;                /*copy back the global value*/
        return(val);
@@ -387,19 +437,18 @@ readonly short type[] = {
  */
 #define        HEXFLAG         01              /* 'x' or 'X' */
 #define        HEXLDIGIT       02              /* 'a' .. 'f' */
  */
 #define        HEXFLAG         01              /* 'x' or 'X' */
 #define        HEXLDIGIT       02              /* 'a' .. 'f' */
-#define HEXUDIGIT      04              /* 'A' .. 'F' */
+#define        HEXUDIGIT       04              /* 'A' .. 'F' */
 #define        ALPHA           010             /* 'A' .. 'Z', 'a' .. 'z', '_'*/
 #define        ALPHA           010             /* 'A' .. 'Z', 'a' .. 'z', '_'*/
-#define DIGIT          020             /* '0' .. '9' */
+#define        DIGIT           020             /* '0' .. '9' */
 #define        FLOATEXP        040             /* 'd' 'e' 'D' 'E' */
 #define        FLOATEXP        040             /* 'd' 'e' 'D' 'E' */
-                                               /*exponent field*/
-#define SIGN           0100            /* '+' .. '-'*/
-#define REGDIGIT       0200            /* '0' .. '5' */
-#define SZSPECBEGIN    0400            /* 'b', 'B', 'l', 'L', 'w', 'W' */
-#define POINT          01000           /* '.' */
-#define SPACE          02000           /* '\t' or ' ' */
-#define BSESCAPE       04000           /* bnrtf */
-#define STRESCAPE      010000          /* '"', '\\', '\n' */
-#define OCTDIGIT       020000          /* '0' .. '7' */
+#define        SIGN            0100            /* '+' .. '-'*/
+#define        REGDIGIT        0200            /* '0' .. '5' */
+#define        SZSPECBEGIN     0400            /* 'b', 'B', 'l', 'L', 'w', 'W' */
+#define        POINT           01000           /* '.' */
+#define        SPACE           02000           /* '\t' or ' ' */
+#define        BSESCAPE        04000           /* bnrtf */
+#define        STRESCAPE       010000          /* '"', '\\', '\n' */
+#define        OCTDIGIT        020000          /* '0' .. '7' */
 #define        FLOATFLAG       040000          /* 'd', 'D', 'f', 'F' */
                                                /*after leading 0*/
 
 #define        FLOATFLAG       040000          /* 'd', 'D', 'f', 'F' */
                                                /*after leading 0*/
 
@@ -408,7 +457,8 @@ readonly short charsets[] = {
        0,      SPACE,  STRESCAPE,0,    0,      0,      0,      0,   /*BS..SI*/
        0,      0,      0,      0,      0,      0,      0,      0,   /*DLE..ETB*/
        0,      0,      0,      0,      0,      0,      0,      0,   /*CAN..US*/
        0,      SPACE,  STRESCAPE,0,    0,      0,      0,      0,   /*BS..SI*/
        0,      0,      0,      0,      0,      0,      0,      0,   /*DLE..ETB*/
        0,      0,      0,      0,      0,      0,      0,      0,   /*CAN..US*/
-       SPACE,  0,      STRESCAPE,0,    0,      0,      0,      0,   /*sp.. '*/
+/* dollar is an alpha character */
+       SPACE,  0,      STRESCAPE,0,    ALPHA,  0,      0,      0,   /*sp.. '*/
        0,      0,      0,      SIGN,   0,      SIGN,   POINT+ALPHA,0, /*( .. /*/
        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*0..1*/
        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*2..3*/
        0,      0,      0,      SIGN,   0,      SIGN,   POINT+ALPHA,0, /*( .. /*/
        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*0..1*/
        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*2..3*/
@@ -438,46 +488,80 @@ readonly short charsets[] = {
        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,0,    0,      0,      0,    /*x..del*/
 0};
 
        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,0,    0,      0,      0,    /*x..del*/
 0};
 
-#define INCHARSET(val, kind) (charsets[val] & (kind) )
+#define        INCHARSET(val, kind) (charsets[val] & (kind) )
 static toktype oval = NL;
 
 static toktype oval = NL;
 
-#define INBUFLG 2 + 2*BUFSIZ + 128
+#define        NINBUFFERS      2
+#define        INBUFLG         NINBUFFERS*BUFSIZ + 2
+       /*
+        *      We have two input buffers; the first one is reserved
+        *      for catching the tail of a line split across a buffer
+        *      boundary; the other one are used for snarfing a buffer
+        *      worth of .s source.
+        */
 static char    inbuffer[INBUFLG];
 static char    *InBufPtr = 0;
 
 static char    inbuffer[INBUFLG];
 static char    *InBufPtr = 0;
 
-#ifdef  getchar
-#undef getchar
+#ifdef getchar
+#undef         getchar
 #endif
 #endif
-#define getchar() *inbufptr++
+#define        getchar() *inbufptr++
 
 
-#ifdef  ungetc
-#undef ungetc
+#ifdef ungetc
+#undef         ungetc
 #endif
 #endif
-#define        ungetc(char, fileptr) *--inbufptr = char
+#define        ungetc(char) *--inbufptr = char
 
 
+/*
+ *     fill the inbuffer from the standard input.
+ *     Assert: there are always n COMPLETE! lines in the buffer area.
+ *     Assert: there is always a \n terminating the last line
+ *             in the buffer area.
+ *     Assert: after the \n, there is an EOFCHAR (hard end of file)
+ *             or a NEEDCHAR (end of buffer)
+ *     Assert: fgets always null pads the string it reads.
+ *     Assert: no ungetc's are done at the end of a line or at the
+ *             beginning of a line.
+ *     
+ *     We read a complete buffer of characters in one single read.
+ *     We then back scan within this buffer to find the end of the
+ *     last complete line, and force the assertions, and save a pointer
+ *     to the incomplete line.
+ *     The next call to fillinbuffer will move the unread characters
+ *     to the end of the first buffer, and then read another two buffers,
+ *     completing the cycle.
+ */
+
+static char    p_swapped = '\0';                       
+static char    *p_start = &inbuffer[NINBUFFERS * BUFSIZ];
+static char    *p_stop = &inbuffer[NINBUFFERS * BUFSIZ];
 char *fillinbuffer()
 {
 char *fillinbuffer()
 {
-       register        char    *cp, *inbufptr;
+       register        char    *to;
+       register        char    *from;
+                       char    *inbufptr;
        int             nread;
 
        int             nread;
 
-       inbufptr = &inbuffer[2];        /*allow enough room for two ungetcs*/
-       nread = fread(inbufptr, 1, 2*BUFSIZ, stdin);
-       if (nread == 2*BUFSIZ){
-               cp = fgets(inbufptr+2*BUFSIZ, 128, stdin);      /*get next whole line*/
-               if (cp != 0){
-                       while(*cp++);   /*find the trailing null*/
-                       *--cp = NEEDCHAR;       /*clobber with a NEED character*/
-                       return(inbufptr);
-               } else {
-                       *(inbufptr + 2*BUFSIZ) = EOFCHAR;
-                       return(inbufptr);
-               }
-       } else {
-               if (nread == 0)         /*hard end of file*/
-                       return(0);
-               inbuffer[2+nread] = EOFCHAR;
-               return(inbufptr);
-       }
+       *p_start = p_swapped;
+       inbufptr = &inbuffer[1*BUFSIZ] - (p_stop - p_start);
+
+       for (to = inbufptr, from = p_start; from < p_stop;)
+               *to++ = *from++;
+       /*
+        *      Now, go read two full buffers (hopefully)
+        */
+       nread = read(stdin->_file, &inbuffer[1*BUFSIZ], (NINBUFFERS - 1)*BUFSIZ);
+       if (nread == 0)
+               return(0);
+       p_stop = from = &inbuffer[1*BUFSIZ + nread];
+       *from = '\0';
+       while (*--from != '\n')         /* back over the partial line */
+               continue;
+       from++;                         /* first char of partial line */
+       p_start = from;
+       p_swapped = *p_start;
+       *p_start = NEEDCHAR;            /* force assertion */
+       return(inbufptr);
 }
 
 scan_dot_s(bufferbox)
 }
 
 scan_dot_s(bufferbox)
@@ -490,6 +574,7 @@ scan_dot_s(bufferbox)
        register        char    *inbufptr;
        register        struct          symtab  *op;
        register        unsigned        char    tag;
        register        char    *inbufptr;
        register        struct          symtab  *op;
        register        unsigned        char    tag;
+       int             forb;
 
        register        ptrall  bufptr;         /*where to stuff tokens*/
                        ptrall  lgbackpatch;    /*where to stuff a string length*/
 
        register        ptrall  bufptr;         /*where to stuff tokens*/
                        ptrall  lgbackpatch;    /*where to stuff a string length*/
@@ -497,9 +582,13 @@ scan_dot_s(bufferbox)
        register        int     maxstrlg;       /*how long a string can be*/
                        long    intval;         /*value of int*/
                        char    fltchr[64];     /*buffer for floating values*/
        register        int     maxstrlg;       /*how long a string can be*/
                        long    intval;         /*value of int*/
                        char    fltchr[64];     /*buffer for floating values*/
-                       double  fltval;         /*floating value returned*/
+               union   Double  fltval;         /*floating value returned*/
+               struct  Quad    quadval;        /*quad returned from immediate constant */
                        int     linescrossed;   /*when doing strings and comments*/
 
                        int     linescrossed;   /*when doing strings and comments*/
 
+       (toktype *)bufptr = (toktype *) & (bufferbox->toks[0]); 
+       (toktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
+
        inbufptr = InBufPtr;
        if (inbufptr == 0){
                inbufptr = fillinbuffer();
        inbufptr = InBufPtr;
        if (inbufptr == 0){
                inbufptr = fillinbuffer();
@@ -511,15 +600,7 @@ scan_dot_s(bufferbox)
                }
        }
 
                }
        }
 
-       (toktype *)bufptr = (toktype *) & (bufferbox->toks[0]); 
-       (toktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
-
        if (newfflag){
        if (newfflag){
-#ifdef DEBUG
-       if (debug)
-               printf(">>>>>>>>>>>>>(scanner) Starting to insert tokens into a new file: %s\n",
-                               newfname);
-#endif
                ptoken(bufptr, IFILE);
                ptoken(bufptr, STRING);
                val = strlen(newfname) + 1;
                ptoken(bufptr, IFILE);
                ptoken(bufptr, STRING);
                val = strlen(newfname) + 1;
@@ -534,339 +615,417 @@ scan_dot_s(bufferbox)
 
        while (bufptr < bufub){
    loop:
 
        while (bufptr < bufub){
    loop:
-           switch(yylval = (type+2)[val = getchar()]) {
-               case SCANEOF:
-                       inbufptr = 0;
+        switch(yylval = (type+2)[val = getchar()]) {
+       case SCANEOF:
+               inbufptr = 0;
+               goto endoffile;
+
+       case NEEDSBUF:
+               inbufptr = fillinbuffer();
+               if (inbufptr == 0)
                        goto endoffile;
                        goto endoffile;
+               goto loop;
 
 
-               case NEEDSBUF:
-                       inbufptr = fillinbuffer();
-                       if (inbufptr == 0)
-                               goto endoffile;
-                       goto loop;
-
-               case DIV:               /*process C style comments*/
-                       if ( (val = getchar()) == '*') {  /*comment prelude*/
-                               int     incomment;
-                               linescrossed = 0;
-                               incomment = 1;
-                               val = getchar();        /*skip over the * */
-                               do{
-                                       while ( (val != '*') &&
-                                               (val != '\n') &&
-                                               (val != EOFCHAR) &&
-                                               (val != NEEDCHAR))
-                                                       val = getchar();
-                                       if (val == '\n'){
-                                               scanlineno++;
-                                               linescrossed++;
-                                       } else
-                                       if (val == EOFCHAR)
-                                               goto endoffile;
-                                       if (val == NEEDCHAR){
-                                               inbufptr = fillinbuffer();
-                                               if (inbufptr == 0)
-                                                       goto endoffile;
-                                               lineno++;
-                                               incomment = 1;
-                                               val = getchar(); /*pull in the new char*/
-                                       } else {        /*its a star */
+       case DIV:               /*process C style comments*/
+               if ( (val = getchar()) == '*') {  /*comment prelude*/
+                       int     incomment;
+                       linescrossed = 0;
+                       incomment = 1;
+                       val = getchar();        /*skip over the * */
+                       do{
+                               while ( (val != '*') &&
+                                       (val != '\n') &&
+                                       (val != EOFCHAR) &&
+                                       (val != NEEDCHAR))
                                                val = getchar();
                                                val = getchar();
-                                               incomment = val != '/';
-                                       }
-                               } while (incomment);
-                               val = ILINESKIP;
-                               yylval = linescrossed;
-                               goto ret;
-                       } else {        /*just an ordinary DIV*/
-                               ungetc(val, stdin);
-                               val = yylval = DIV;
-                               goto ret;
-                       }
-               case SH:
-                       if (oval == NL){
-                               /*
-                                *      Attempt to recognize a C preprocessor
-                                *      style comment '^#[ \t]*[0-9]*[ \t]*".*"
-                                */
-                               val = getchar();        /*bump the #*/
+                               if (val == '\n'){
+                                       scanlineno++;
+                                       linescrossed++;
+                               } else
+                               if (val == EOFCHAR)
+                                       goto endoffile;
+                               if (val == NEEDCHAR){
+                                       inbufptr = fillinbuffer();
+                                       if (inbufptr == 0)
+                                               goto endoffile;
+                                       lineno++;
+                                       incomment = 1;
+                                       val = getchar(); /*pull in the new char*/
+                               } else {        /*its a star */
+                                       val = getchar();
+                                       incomment = val != '/';
+                               }
+                       } while (incomment);
+                       val = ILINESKIP;
+                       yylval = linescrossed;
+                       goto ret;
+               } else {        /*just an ordinary DIV*/
+                       ungetc(val);
+                       val = yylval = DIV;
+                       goto ret;
+               }
+       case SH:
+               if (oval == NL){
+                       /*
+                        *      Attempt to recognize a C preprocessor
+                        *      style comment '^#[ \t]*[0-9]*[ \t]*".*"
+                        */
+                       val = getchar();        /*bump the #*/
+                       while (INCHARSET(val, SPACE))
+                               val = getchar();/*bump white */
+                       if (INCHARSET(val, DIGIT)){
+                               intval = 0;
+                               while(INCHARSET(val, DIGIT)){
+                                       intval = intval *10 + val - '0';
+                                       val = getchar();
+                               }
                                while (INCHARSET(val, SPACE))
                                while (INCHARSET(val, SPACE))
-                                       val = getchar();/*bump white */
-                               if (INCHARSET(val, DIGIT)){
-                                       intval = 0;
-                                       while(INCHARSET(val, DIGIT)){
-                                               intval = intval *10 + val - '0';
-                                               val = getchar();
-                                       }
-                                       while (INCHARSET(val, SPACE))
-                                               val = getchar();
-                                       if (val == '"'){
-                                               ptoken(bufptr, ILINENO);
-                                               ptoken(bufptr, INT);
-                                               pint(bufptr, intval - 1);
-                                               ptoken(bufptr, IFILE);
-                                               /*
-                                                *      The '"' has already been
-                                                *      munched
-                                                *      
-                                                *      eatstr will not eat
-                                                *      the trailing \n, so
-                                                *      it is given to the parser
-                                                *      and counted.
-                                                */
-                                               goto eatstr;
-                                       }
+                                       val = getchar();
+                               if (val == '"'){
+                                       ptoken(bufptr, ILINENO);
+                                       ptoken(bufptr, INT);
+                                       pint(bufptr, intval - 1);
+                                       ptoken(bufptr, IFILE);
+                                       /*
+                                        *      The '"' has already been
+                                        *      munched
+                                        *      
+                                        *      eatstr will not eat
+                                        *      the trailing \n, so
+                                        *      it is given to the parser
+                                        *      and counted.
+                                        */
+                                       goto eatstr;
                                }
                        }
                                }
                        }
+               }
+               /*
+                *      Well, its just an ordinary decadent comment
+                */
+               while ((val != '\n') && (val != EOFCHAR)) 
+                       val = getchar();
+               if (val == EOFCHAR)
+                       goto endoffile;
+               val = yylval = oval = NL;
+               scanlineno++;
+               goto ret;
+
+       case NL:
+               scanlineno++;
+               val = yylval;
+               goto ret;
+
+       case SP:
+               oval = SP;      /*invalidate ^# meta comments*/
+               goto loop;
+
+       case REGOP:             /* % , could be used as modulo, or register*/
+               val = getchar();
+               if (INCHARSET(val, DIGIT)){
+                       yylval = val-'0';
+                       if (val=='1') {
+                               if (INCHARSET( (val = getchar()), REGDIGIT))
+                                       yylval = 10+val-'0';
+                               else
+                                       ungetc(val);
+                       }
                        /*
                        /*
-                        *      Well, its just an ordinary decadent comment
+                        *      God only knows what the original author
+                        *      wanted this undocumented feature to
+                        *      do.
+                        *              %5++ is really  r7
                         */
                         */
-                       while ((val != '\n') && (val != EOFCHAR)) 
-                               val = getchar();
-                       if (val == EOFCHAR)
-                               goto endoffile;
-                       val = yylval = oval = NL;
-                       scanlineno++;
+                       while(INCHARSET( (val = getchar()), SIGN)) {
+                               if (val=='+')
+                                       yylval++;
+                               else
+                                       yylval--;
+                       }
+                       ungetc(val);
+                       val = REG;
+               } else {
+                       ungetc(val);
+                       val = REGOP;
+               }
+               goto ret;
+
+       case ALPH:
+               yylval = val;
+               if (INCHARSET(val, SZSPECBEGIN)){
+                       if( (val = getchar()) == '`' || val == '^'){
+                               yylval |= 0100; /*convert to lower*/
+                               if (yylval == 'b') yylval = 1;
+                               else if (yylval == 'w') yylval = 2;
+                               else if (yylval == 'l') yylval = 4;
+                               else                    yylval = d124;
+                               val = SIZESPEC;
+                               goto ret;
+                       } else {
+                               ungetc(val);
+                               val = yylval;   /*restore first character*/
+                       }
+               }
+               cp = yytext;
+               do {
+                       if (cp < &yytext[NCPS])
+                               *cp++ = val;
+               } while (INCHARSET ( (val = getchar()), ALPHA | DIGIT));
+               *cp = '\0';
+               while (INCHARSET(val, SPACE))
+                       val = getchar();
+               ungetc(val);
+       doit:
+               tag = (op = *lookup(1))->s_tag;
+               if (tag && tag != LABELID){
+                       yylval = ( (struct instab *)op)->i_opcode;
+                       val = op->s_tag ;
                        goto ret;
                        goto ret;
-       
-               case NL:
-                       scanlineno++;
-                       val = yylval;
+               } else {
+                       /*
+                        *      Its a name... (Labels are subsets ofname)
+                        */
+                       yylval = (int)op;
+                       val = NAME;
                        goto ret;
                        goto ret;
+               }
 
 
-               case SP:
-                       oval = SP;      /*invalidate ^# meta comments*/
-                       goto loop;
-       
-               case REGOP:             /* % , could be used as modulo, or register*/
+       case DIG:
+               base = 10;
+               cp = fltchr;
+               intval = 0;
+               if (val=='0') {
                        val = getchar();
                        val = getchar();
-                       if (INCHARSET(val, DIGIT)){
-                               yylval = val-'0';
-                               if (val=='1') {
-                                       if (INCHARSET( (val = getchar()), REGDIGIT))
-                                               yylval = 10+val-'0';
-                                       else
-                                               ungetc(val, stdin);
-                               }
+                       if (val == 'b') {
+                               yylval = -1;
+                               val = BFINT;
+                               goto ret;
+                       } 
+                       if (val == 'f') {
                                /*
                                /*
-                                *      God only knows what the original author
-                                *      wanted this undocumented feature to
-                                *      do.
-                                *              %5++ is really  r7
+                                *      Well, it appears to be a local label
+                                *      reference, but check to see if
+                                *      the next character makes it a floating
+                                *      point constant.
                                 */
                                 */
-                               while(INCHARSET( (val = getchar()), SIGN)) {
-                                       if (val=='+')
-                                               yylval++;
-                                       else
-                                               yylval--;
+                               forb = getchar();
+                               ungetc(forb);
+                               if (!(INCHARSET(forb,(DIGIT|SIGN|FLOATEXP|POINT)))){
+                                       yylval = 1;
+                                       val = BFINT;
+                                       goto ret;
                                }
                                }
-                               ungetc(val, stdin);
-                               val = REG;
-                       } else {
-                               ungetc(val, stdin);
-                               val = REGOP;
                        }
                        }
-                       goto ret;
-       
-               case ALPH:
-                       yylval = val;
-                       if (INCHARSET(val, SZSPECBEGIN)){
-                               if( (val = getchar()) == '`' || val == '^'){
-                                       yylval |= 0100; /*convert to lower*/
-                                       if (yylval == 'b') yylval = 1;
-                                       else if (yylval == 'w') yylval = 2;
-                                       else if (yylval == 'l') yylval = 4;
-                                       else                    yylval = d124;
-                                       val = SIZESPEC;
+                       if (INCHARSET(val, HEXFLAG)){
+                               base = 16;
+                       } else
+                       if (INCHARSET(val, FLOATFLAG)){
+                               double atof();
+                               while ( (cp < &fltchr[63]) &&
+                                       INCHARSET(
+                                               (val=getchar()),
+                                               (DIGIT|SIGN|FLOATEXP|POINT)
+                                             )
+                                     ) *cp++ = val;
+                               if (cp == fltchr) {
+                                       yylval = 1;
+                                       val = BFINT;
                                        goto ret;
                                        goto ret;
-                               } else {
-                                       ungetc(val, stdin);
-                                       val = yylval;   /*restore first character*/
                                }
                                }
-                       }
-                       cp = yytext;
-                       do {
-                               if (cp < &yytext[NCPS])
-                                       *cp++ = val;
-                       } while (INCHARSET ( (val = getchar()), ALPHA | DIGIT));
-                       *cp = '\0';
-                       while (INCHARSET(val, SPACE))
-                               val = getchar();
-                       ungetc(val, stdin);
-                       tag = (op = *lookup(1))->tag;
-                       if (tag && tag != LABELID){
-                               yylval = ( (struct instab *)op)->opcode;
-                               val = op->tag ;
+                               ungetc(val);
+                               *cp++ = '\0';
+                               fltval.dvalue = atof(fltchr);
+                               val = FLTNUM;
                                goto ret;
                        } else {
                                goto ret;
                        } else {
-                               /*
-                                *      Its a name... (Labels are subsets ofname)
-                                */
-                               yylval = (int)op;
-                               val = NAME;
-                               goto ret;
+                               ungetc(val);
+                               base = 8;
                        }
                        }
-       
-               case DIG:
-                       intval = val-'0';
-                       if (val=='0') {
-                               val = getchar();
-                               if (INCHARSET(val, HEXFLAG)){
-                                       base = 16;
-                               } else
-                               if (INCHARSET(val, FLOATFLAG)){
-                                       char *p = fltchr;
-                                       double atof();
-       
-                                       while ( (p < &fltchr[63]) &&
-                                               INCHARSET(
-                                                       (val=getchar()),
-                                                       (DIGIT|SIGN|FLOATEXP|POINT)
-                                                     )
-                                             ) *p++ = val;
-                                       ungetc(val, stdin);
-                                       *p++ = '\0';
-                                       fltval = atof(fltchr);
-                                       val = FLTNUM;
-                                       goto ret;
-                               } else {
-                                       ungetc(val, stdin);
-                                       base = 8;
-                               }
-                       } else
-                               base = 10;
-                       while ( INCHARSET( (val = getchar()), DIGIT) || 
-                               (base==16 && (INCHARSET(val, HEXLDIGIT|HEXUDIGIT) )
-                                  )
-                             ){
-                               if (base==8)
-                                       intval <<= 3;
-                               else if (base==10)
-                                       intval *= 10;
-                               else {
-                                       intval <<= 4;
-                                       if (INCHARSET(val, HEXLDIGIT))
-                                               val -= 'a' - 10 - '0';
-                                       else if (INCHARSET(val, HEXUDIGIT))
-                                               val -= 'A' - 10 - '0';
-                               }
-                               intval += val-'0';
+               } else {
+                       forb = getchar();
+                       if (forb == 'f' || forb == 'b') {
+                               yylval = val - '0' + 1;
+                               if (forb == 'b')
+                                       yylval = -yylval;
+                               val = BFINT;
+                               goto ret;
                        }
                        }
-                       ungetc(val, stdin);
-                       val = INT;
-                       goto ret;
-       
-               case LSH:
-               case RSH:
-                       /*
-                        *      We allow the C style operators
-                        *      << and >>, as well as < and >
-                        */
-                       if ( (base = getchar()) != val)
-                               ungetc(base, stdin);
-                       val = yylval;
-                       goto ret;
-
-               case MINUS:
-                       if ( (val = getchar()) =='(')
-                               yylval=val=MP;
+                       ungetc(forb);   /* put back non zero */
+                       goto middle;
+               }
+               while ( (val = getchar()) == '0')
+                       continue;
+               ungetc(val);
+               while ( INCHARSET( (val = getchar()), DIGIT) || 
+                       (base==16 && (INCHARSET(val, HEXLDIGIT|HEXUDIGIT) )
+                          )
+                     ){
+                       if (base==8)
+                               intval <<= 3;
+                       else if (base==10)
+                               intval *= 10;
                        else {
                        else {
-                               ungetc(val,stdin);
-                               val=MINUS;
+                               intval <<= 4;
+                               if (INCHARSET(val, HEXLDIGIT))
+                                       val -= 'a' - 10 - '0';
+                               else if (INCHARSET(val, HEXUDIGIT))
+                                       val -= 'A' - 10 - '0';
                        }
                        }
-                       goto ret;
-       
-               case SQ:
-                       if ((yylval = getchar()) == '\n')
-                               scanlineno++;           /*not entirely correct*/
-                       intval = yylval;
+middle:
+                       *cp++ = (val -= '0');
+                       intval += val;
+               }
+               ungetc(val);
+               *cp = 0;
+               maxstrlg = cp - fltchr;
+               if (   (maxstrlg > 8)
+                   && (   (   (base == 8)
+                           && (   (maxstrlg>11)
+                               || (   (maxstrlg == 11)
+                                   && (*fltchr > 3)
+                                  )
+                               )
+                          )
+                       || (   (base == 16)
+                           && (maxstrlg > 8)
+                          )
+                       || (   (base == 10)
+                           && (maxstrlg >= 10)
+                          )
+                       )
+               ) {
+                       val = QUAD;
+                       get_quad(base, fltchr, cp, &quadval);
+               } else
                        val = INT;
                        val = INT;
-                       goto ret;
-       
-               case DQ:
-                  eatstr:
-                       linescrossed = 0;
-                       maxstrlg = (char *)bufub - (char *)bufptr;
+               goto ret;
 
 
-                       if (maxstrlg < MAXSTRLG) {
-                               ungetc('"', stdin);
-                               *(toktype *)bufptr = VOID ;
-                               bufub = bufptr;
-                               goto done;
-                       }
-                       if (maxstrlg > MAXSTRLG)
-                               maxstrlg = MAXSTRLG;
-                       
-                       ptoken(bufptr, STRING);
-                       lgbackpatch = bufptr;   /*this is where the size goes*/
-                       bufptr += sizeof(lgtype);
-                       /*
-                        *      bufptr is now set to
-                        *      be stuffed with characters from
-                        *      the input
-                        */
+       case LSH:
+       case RSH:
+               /*
+                *      We allow the C style operators
+                *      << and >>, as well as < and >
+                */
+               if ( (base = getchar()) != val)
+                       ungetc(base);
+               val = yylval;
+               goto ret;
 
 
-                       while (   (maxstrlg > 0)
-                              && !(INCHARSET( (val = getchar()), STRESCAPE))
-                             ){
-                               stuff:
-                                       maxstrlg-= 1;
-                                       pchar(bufptr, val);
-                               }
-                       if (maxstrlg <= 0){     /*enough characters to fill a string buffer*/
-                               ungetc('"', stdin);             /*will read it next*/
+       case MINUS:
+               if ( (val = getchar()) =='(')
+                       yylval=val=MP;
+               else {
+                       ungetc(val);
+                       val=MINUS;
+               }
+               goto ret;
+
+       case SQ:
+               if ((yylval = getchar()) == '\n')
+                       scanlineno++;           /*not entirely correct*/
+               intval = yylval;
+               val = INT;
+               goto ret;
+
+       case DQ:
+          eatstr:
+               linescrossed = 0;
+               maxstrlg = (char *)bufub - (char *)bufptr;
+
+               if (maxstrlg < MAXSTRLG) {
+                       ungetc('"');
+                       *(toktype *)bufptr = VOID ;
+                       bufub = bufptr;
+                       goto done;
+               }
+               if (maxstrlg > MAXSTRLG)
+                       maxstrlg = MAXSTRLG;
+               
+               ptoken(bufptr, STRING);
+               lgbackpatch = bufptr;   /*this is where the size goes*/
+               bufptr += sizeof(lgtype);
+               /*
+                *      bufptr is now set to
+                *      be stuffed with characters from
+                *      the input
+                */
+
+               while (   (maxstrlg > 0)
+                      && !(INCHARSET( (val = getchar()), STRESCAPE))
+                     ){
+                       stuff:
+                               maxstrlg-= 1;
+                               pchar(bufptr, val);
                        }
                        }
-                       else if (val == '"');           /*done*/
-                       else if (val == '\n'){
-                               scanlineno++;
-                               linescrossed++;
+               if (maxstrlg <= 0){     /*enough characters to fill a string buffer*/
+                       ungetc('"');            /*will read it next*/
+               }
+               else if (val == '"');           /*done*/
+               else if (val == '\n'){
+                       yywarning("New line embedded in a string constant.");
+                       scanlineno++;
+                       linescrossed++;
+                       val = getchar();
+                       if (val == EOFCHAR){
+                         do_eof:
+                               pchar(bufptr, '\n');
+                               ungetc(EOFCHAR);
+                       } else
+                       if (val == NEEDCHAR){
+                               if ( (inbufptr = fillinbuffer()) == 0)
+                                       goto do_eof;
+                               val = '\n';
                                goto stuff;
                                goto stuff;
-                       } else {
-                               val = getchar();                /*skip the '\\'*/
-                               if ( INCHARSET(val, BSESCAPE)){
-                                       switch (val){
-                                         case 'b':  val = '\b'; goto stuff;
-                                         case 'f':  val = '\f'; goto stuff;
-                                         case 'n':  val = '\n'; goto stuff;
-                                         case 'r':  val = '\r'; goto stuff;
-                                         case 't':  val = '\t'; goto stuff;
-                                       }
-                               }
-                               if ( !(INCHARSET(val,OCTDIGIT)) )  goto stuff;
-                               base = 0;
-                               intval = 0;
-                               while ( (base < 3) && (INCHARSET(val, OCTDIGIT))){
-                                       base++;intval <<= 3;intval += val - '0';
-                                       val = getchar();
-                               }
-                               ungetc(val, stdin);
-                               val = (char)intval;
+                       } else {        /* simple case */
+                               ungetc(val);
+                               val = '\n';
                                goto stuff;
                        }
                                goto stuff;
                        }
-                       /*
-                        *      bufptr now points at the next free slot
-                        */
-                       bstrfromto(lgbackpatch, bufptr);
-                       if (linescrossed){
-                               val = ILINESKIP;
-                               yylval = linescrossed;
-                               goto ret;
-                       } else
-                               goto builtval;
-       
-               case BADCHAR:
-                       linescrossed = lineno;
-                       lineno = scanlineno;
-                       yyerror("Illegal character mapped: %d, char read:(octal) %o",
-                               yylval, val);
-                       lineno = linescrossed;
-                       val = BADCHAR;
-                       goto ret;
-       
-               default:
-                       val = yylval;
+               } else {
+                       val = getchar();                /*skip the '\\'*/
+                       if ( INCHARSET(val, BSESCAPE)){
+                               switch (val){
+                                 case 'b':  val = '\b'; goto stuff;
+                                 case 'f':  val = '\f'; goto stuff;
+                                 case 'n':  val = '\n'; goto stuff;
+                                 case 'r':  val = '\r'; goto stuff;
+                                 case 't':  val = '\t'; goto stuff;
+                               }
+                       }
+                       if ( !(INCHARSET(val,OCTDIGIT)) )  goto stuff;
+                       base = 0;
+                       intval = 0;
+                       while ( (base < 3) && (INCHARSET(val, OCTDIGIT))){
+                               base++;intval <<= 3;intval += val - '0';
+                               val = getchar();
+                       }
+                       ungetc(val);
+                       val = (char)intval;
+                       goto stuff;
+               }
+               /*
+                *      bufptr now points at the next free slot
+                */
+               bstrfromto(lgbackpatch, bufptr);
+               if (linescrossed){
+                       val = ILINESKIP;
+                       yylval = linescrossed;
                        goto ret;
                        goto ret;
-               }       /*end of the switch*/
+               } else
+                       goto builtval;
+
+       case BADCHAR:
+               linescrossed = lineno;
+               lineno = scanlineno;
+               yyerror("Illegal character mapped: %d, char read:(octal) %o",
+                       yylval, val);
+               lineno = linescrossed;
+               val = BADCHAR;
+               goto ret;
+
+       default:
+               val = yylval;
+               goto ret;
+       }       /*end of the switch*/
        /*
         *      here with one token, so stuff it
         */
        /*
         *      here with one token, so stuff it
         */
@@ -880,9 +1039,14 @@ scan_dot_s(bufferbox)
                case    SIZESPEC:
                                pchar(bufptr, yylval);
                                break;
                case    SIZESPEC:
                                pchar(bufptr, yylval);
                                break;
+               case    BFINT:  plong(bufptr, yylval);
+                               break;
                case    INT:    plong(bufptr, intval);
                                break;
                case    INT:    plong(bufptr, intval);
                                break;
-               case    FLTNUM: pdouble(bufptr, fltval);
+               case    QUAD:   plong(bufptr, quadval.quad_low_long);
+                               plong(bufptr, quadval.quad_high_long);
+                               break;
+               case    FLTNUM: pdouble(bufptr, fltval.dvalue);
                                break;
                case    NAME:   pptr(bufptr, (int)(struct symtab *)yylval);
                                break;
                                break;
                case    NAME:   pptr(bufptr, (int)(struct symtab *)yylval);
                                break;
@@ -932,3 +1096,35 @@ scan_dot_s(bufferbox)
        ptoken(bufptr, MINUS);
        InBufPtr = inbufptr;            /*copy this back*/
 }
        ptoken(bufptr, MINUS);
        InBufPtr = inbufptr;            /*copy this back*/
 }
+
+struct Quad _quadtemp;
+get_quad(radix, cp_start, cp_end, quadptr)
+       int     radix;
+       char    *cp_start, *cp_end;
+       struct  Quad *quadptr;
+{
+       register                char    *cp = cp_start; /* r11 */
+       register        struct  Quad    *qp = quadptr;  /* r10 */
+       register        long    temp;                   /* r9 */
+
+       asm("clrq (r10)");
+       for (; cp < cp_end; cp++){
+               switch (radix) {
+                       case 8:
+                               asm ("ashq $3, (r10), (r10)");
+                               break;
+                       case 16:
+                               asm ("ashq $4, (r10), (r10)");
+                               break;
+                       case 10:
+                               asm ("ashq      $1, (r10), __quadtemp");
+                               asm ("ashq      $3, (r10), (r10)");
+                               asm ("addl2     __quadtemp, (r10)");
+                               asm ("adwc      __quadtemp+4, 4(r10)");
+                               break;
+               }
+               asm ("cvtbl     (r11), r9");
+               asm ("addl2     r9, (r10)");
+               asm ("adwc      $0, 4(r10)");
+       }
+}