# getsym --- get next symbol from input stream

   subroutine getsym

   include XREF_COMMON

   integer radix, i
   integer index
   character c, quote
   character ngetch

   repeat {    # until a symbol is found
      Symlen = 0
      Symtext (1) = EOS
      Sym_name (1) = EOS

      call ngetch (c)
      call skip_blanks_and_comments (c)

      select (c)
         when (SET_OF_LETTERS) {
            i = 0
            repeat {
               Symlen += 1
               Symtext (Symlen) = c
               if (c ~= '_'c) {
                  i += 1
                  Sym_name (i) = c
                  }
               call ngetch (c)
               } until (~IS_LETTER (c) && ~IS_DIGIT (c)
                                       && c ~= '_'c && c ~= '$'c)
            call putback (c)
            Symtext (Symlen + 1) = EOS
            Sym_name (i + 1) = EOS
            Symbol = IDSYM
            break
            }  # end of identifier processing

         when (SET_OF_DIGITS) {     # Integer
            while (IS_DIGIT (c)) {
               Symlen += 1
               Symtext (Symlen) = c
               call ngetch (c)
               }
            if (c == 'r'c) {        # radix specified
               Symlen += 1
               Symtext (Symlen) = 'r'c
               while (index ("0123456789abcdefABCDEF"s, ngetch (c)) ~= 0) {
                  Symlen += 1
                  Symtext (Symlen) = c
                  }
               }
            Symtext (Symlen + 1) = EOS
            call putback (c)
            Symbol = NUMBERSYM
            break
            }  # end of integer processing

         when ('"'c, "'"c) {
            Symbol = STRCONSTANTSYM
            quote = c
            repeat {
               Symlen += 1
               if (Symlen >= MAXTOK) {
                  SYNERR ("Quoted literal too long"p)
                  break 2
                  }
               Symtext (Symlen) = c
               if (c == NEWLINE) {
                  SYNERR ("Unmatched quote"p)
                  call putback (c)
                  c = quote
                  break
                  }
               } until (ngetch (c) == quote)
            Symlen += 1
            Symtext (Symlen) = c
            if ('a'c <= ngetch (c) && c <= 'z') {  # check for format letter
               Symlen += 1
               Symtext (Symlen) = c
               }
            call putback (c)
            Symtext (Symlen + 1) = EOS
            break
            }

      else {   # single_character symbol
         Symbol = c
         Symtext (1) = c
         Symtext (2) = EOS
         Symlen = 1
         break
         }

      }  # repeat until a symbol is found

DB call print (ERROUT, "Symbol = *i, "p, Symbol)
DB call print (ERROUT, "text='*s'*n"p, Sym_text)
   return
   end



# skip_blanks_and_comments --- handle comments, continuations, skip blanks

   subroutine skip_blanks_and_comments (c)
   character c

   repeat {
      while (c == ' 'c) {
         call outch (c)
         call ngetch (c)
         }
       if (c == '#'c) {
         repeat {
            call outch (c)
            call ngetch (c)
            } until (c == NEWLINE)
         }
      } until (c ~= ' 'c)

   return
   end



# ngetch --- get a (possibly pushed back) input character

   character function ngetch (c)
   character c

   include XREF_COMMON

   integer getlin

   if (Inbuf (Ibp) ~= EOS) {
      ngetch = Inbuf (Ibp)
      Ibp = Ibp + 1
      }
   else {
      repeat {
         if (Level < 1) {
            ngetch = EOF
            c = EOF
            Inbuf (PBLIMIT) = EOS
            Ibp = PBLIMIT
            return
            }
         if (getlin (Inbuf (PBLIMIT), Infile (Level)) ~= EOF) {
            Line_number (Level) = Line_number (Level) + 1
            break
            }
         call close (Infile (Level))
         Level = Level - 1
         }
      ngetch = Inbuf (PBLIMIT)
      Ibp = PBLIMIT + 1
      }

   c = ngetch

   return
   end




# putback --- push character back onto input

   subroutine putback (c)
   character c

   include XREF_COMMON

   Ibp = Ibp - 1
   if (Ibp >= 1)
      Inbuf (Ibp) = c
   else
      call error ("too many characters pushed back"p)

   return
   end



# putback_str --- push string back onto input

   subroutine putback_str (str)
   character str (ARB)

   include XREF_COMMON

   integer i
   integer length

   for (i = length (str); i > 0; i = i - 1)
      call putback (str (i))

   return
   end
